# Connect an Agent to DataLinks over A2A Source: https://docs.landfall.ai/a2a/general-a2a Connect any A2A-compliant client or agent framework to a DataLinks agent using the Agent2Agent protocol. DataLinks exposes its agents over the **Agent2Agent (A2A)** protocol, an open standard for programs and agents to talk to each other over HTTP. Every DataLinks agent is a standard **A2A 1.0 server**, so any A2A-compliant client or framework can discover it, authenticate, and stream answers back, without a DataLinks-specific client library. A2A support is in **preview**. It's available to every account with no extra rate limits, but the surface may still change. Prefer native Python without a protocol layer? The DataLinks [Python SDK](/pythonsdk/index) has its own `ask` API. ## Prerequisites Before starting, make sure you have: * A DataLinks API token. See [Get an API token](/how-to/get-api-token). The same token you use for the REST API and SDK works for A2A. * The **namespace** you want the agent to work against. You can find it under **My Data**. * Python 3.10+ (this guide uses the official `a2a-sdk` client; any A2A-compliant client works). ## Install Required Dependencies The reference client uses the official A2A Python SDK and an async HTTP client: ```bash theme={null} uv pip install a2a-sdk httpx ``` If you also use the DataLinks Python SDK for configuration, install it as well: ```bash theme={null} uv pip install datalinks ``` ## Configure Your Environment The client reads standard DataLinks settings from the environment (or a `.env` file): * `DL_HOST` - the DataLinks host that serves the A2A endpoints: `https://api.datalinks.com/api/v1` * `DL_API_KEY` - your DataLinks API token * `DL_NAMESPACE` - the namespace the agent should query * `DL_A2A_AGENT` - *(optional)* the agent to use; defaults to the first agent listed by the server Alternatively, place these values in a `.env` file at the root of your project. ## How the DataLinks A2A Endpoints Work A2A lives under the API base URL. With `DL_HOST` set to `https://api.datalinks.com/api/v1`, DataLinks exposes every agent through three endpoints: | Endpoint | Auth | Purpose | | - | - | - | | `GET {host}/a2a` | Public | List the agents this server exposes | | `GET {host}/a2a/{agent}/.well-known/agent-card.json` | Public | Fetch the agent's **AgentCard** (capabilities and security scheme) | | `POST {host}/a2a/{agent}` | Bearer token | Send messages (JSON-RPC, streaming) | DataLinks currently exposes two agents: | Agent | What it does | | - | - | | `nl2ql` | Turns a plain-language question into a structured query, runs it against your namespace, and returns the generated query plus the result rows. | | `assistant` | Plans a multi-step query strategy, runs the queries, and synthesises an answer. This is the same assistant behind the `ask` endpoint. | The **AgentCard** is the key idea: it's a self-describing manifest that tells your client what the agent can do and how to authenticate. Your client reads the card first, then uses it to configure the connection, so nothing about the auth flow needs to be hardcoded. For the full endpoint, AgentCard, and event specification, see the [A2A Protocol Reference](/reference/a2a-protocol). ## Connect and Ask a Question The flow has five steps: discover agents, resolve the chosen agent's card, register your API key as the bearer credential, send the message with the target namespace, and stream the answer. ```python theme={null} import httpx async def list_agents(http: httpx.AsyncClient, host: str) -> list[dict]: resp = await http.get(f"{host}/a2a") resp.raise_for_status() return resp.json() ``` Your API key is sent as a bearer token for whatever security scheme(s) the card declares (DataLinks declares a single scheme named `bearer`, sent as `Bearer `). ```python theme={null} from a2a.client import ( A2ACardResolver, AuthInterceptor, ClientConfig, ClientFactory, ClientCallContext, InMemoryContextCredentialStore, ) SESSION_ID = "datalinks-a2a-example" agent_base = f"{host}/a2a/{agent_name}" card = await A2ACardResolver(http, base_url=agent_base).get_agent_card() store = InMemoryContextCredentialStore() for requirement in card.security_requirements: for scheme_name in requirement.schemes: await store.set_credentials(SESSION_ID, scheme_name, api_key) ``` Iterating over the card's declared schemes (rather than hardcoding `"bearer"`) keeps your client working if the scheme name ever changes. ```python theme={null} factory = ClientFactory(ClientConfig(httpx_client=http, streaming=True)) client = factory.create(card, interceptors=[AuthInterceptor(store)]) ``` The namespace travels in the message metadata; the server reads `message.metadata.namespace`. You can optionally add `model` and `provider` to the same metadata to steer which LLM the agent uses. ```python theme={null} from uuid import uuid4 from google.protobuf.struct_pb2 import Struct from a2a.types import ( Message, Part, Role, SendMessageConfiguration, SendMessageRequest, ) metadata = Struct() metadata.update({"namespace": namespace}) # optionally: "model", "provider" request = SendMessageRequest( message=Message( message_id=str(uuid4()), role=Role.ROLE_USER, parts=[Part(text=question)], metadata=metadata, ), configuration=SendMessageConfiguration(accepted_output_modes=["text", "data"]), ) ``` ```python theme={null} context = ClientCallContext(state={"sessionId": SESSION_ID}) async for response in client.send_message(request, context=context): render(response) # see "Handling the streamed response" below ``` A complete, runnable version of this client is in the Python SDK examples under [A2A Client (Agent2Agent Protocol)](/pythonsdk/examples#a2a-client-agent2agent-protocol). ## Handling the Streamed Response A2A streaming yields a sequence of typed events, not a single answer. Each event's `payload` is one of `task`, `message`, `status_update`, or `artifact_update`. Within a message or artifact, the content arrives as **parts**, and each part is either a **TextPart** or a **DataPart**. The two agents return their results as named artifacts: * `nl2ql` emits a `generated-query` artifact (the query, as a `TextPart`) and a `result-data` artifact (the rows, as a `DataPart`). * `assistant` streams `working` status updates while it plans and runs steps, a `step-N` artifact per step (the step's query plus its rows), and a final `answer` artifact (the synthesised answer, as a `TextPart`). Handle **both** part types. The query and answer arrive as `TextPart`s, but the **rows come back as a `DataPart`** (under a `rows` key). If you only read text parts, the rows are silently dropped and you'll see the query but not the data. ```python theme={null} from google.protobuf.json_format import MessageToDict from a2a.types import TaskState def render(response) -> None: kind = response.WhichOneof("payload") if kind == "message": _print_parts(response.message.parts) elif kind == "artifact_update": _print_parts(response.artifact_update.artifact.parts) elif kind == "status_update": status = response.status_update.status print(f"[status: {TaskState.Name(status.state)}]") if status.HasField("message"): _print_parts(status.message.parts) elif kind == "task": task = response.task print(f"[task {task.id}: {TaskState.Name(task.status.state)}]") for artifact in task.artifacts: _print_parts(artifact.parts) def _print_parts(parts) -> None: for part in parts: content = part.WhichOneof("content") if content == "text": print(part.text) elif content == "data": payload = MessageToDict(part.data) # protobuf -> native dict/list rows = payload.get("rows") if isinstance(payload, dict) else None print(rows if rows is not None else payload) ``` ## Verify the Connection To confirm everything is working: * `GET {host}/a2a` returns a non-empty list of agents (`nl2ql` and `assistant`). * Fetching the AgentCard for your chosen agent succeeds. * A simple question streams back a `status_update` reaching a completed state, followed by an answer. * No `401`/`403` authorization errors appear. ## Troubleshooting **Authorization errors (401 / 403)** * Confirm your DataLinks API token is correct and current. * Make sure the token is sent as `Bearer ` with no extra spaces. * Confirm the scheme name you registered matches the one the AgentCard declares (`bearer`). **No agents returned** * Confirm `DL_HOST` points at `https://api.datalinks.com/api/v1` (A2A lives under the API base, not the root host). **`message metadata.namespace is required`** * The namespace must live in the **message** metadata (`message.metadata.namespace`), not in the URL, the request-level metadata, or the body. **You see the query but not the data** * You're only handling `TextPart`s. Handle `DataPart`s too (see the warning above); the rows arrive under `part.data.rows`. **Empty or hanging responses** * Increase the HTTP client timeout; some agent runs take longer than the default. * Confirm the `namespace` in the message metadata exists, has at least one dataset, and you have access to it. ## When to Use A2A, MCP, or the SDK DataLinks offers three ways to reach the same data. Pick by how you're building: | You want to... | Use | | - | - | | Talk to a DataLinks **agent** as a peer, from any A2A-compliant
framework | **A2A** (this guide) | | Expose DataLinks as a **tool** inside an AI client (Claude Desktop,
IDEs, agent frameworks that speak MCP) | [MCP](/mcp/general-mcp) | | Write native **Python** with no protocol layer | [Python SDK `ask`](/pythonsdk/examples) | ## Next Steps * Read the [A2A Protocol Reference](/reference/a2a-protocol) for the full endpoint, AgentCard, and event details. * Try the [complete runnable client](/pythonsdk/examples#a2a-client-agent2agent-protocol). * Combine the agent's answers with your own workflow or multi-agent system. # A2A JSON-RPC endpoint for an agent Source: https://docs.landfall.ai/api-reference/a2a/a2a-json-rpc-endpoint-for-an-agent /api-reference/openapi.yml post /a2a/{agentName} JSON-RPC 2.0 endpoint implementing the A2A methods `SendMessage`, `SendStreamingMessage`, `GetTask`, `CancelTask` and `GetExtendedAgentCard`. `SendStreamingMessage` responds with `text/event-stream`; the others with a single JSON-RPC response. `GetExtendedAgentCard` returns the authenticated, richer AgentCard. Protocol errors are returned as JSON-RPC error objects with HTTP 200. The target namespace is supplied in the message `metadata.namespace`; the acting user is taken from the bearer token. Request and response bodies follow the A2A 1.0 spec (https://a2a-protocol.org). An agent whose card advertises the caller-context extension also accepts context established before it was called, as `data` parts tagged with the extension URI; a malformed or oversized payload, or context sent to an agent that does not advertise it, is an `InvalidParams` error. See docs/a2a-caller-context.md. # Fetch an agent's AgentCard Source: https://docs.landfall.ai/api-reference/a2a/fetch-an-agents-agentcard /api-reference/openapi.yml get /a2a/{agentName}/.well-known/agent-card.json Returns the A2A AgentCard describing the agent's skills, capabilities, security schemes and JSON-RPC endpoint. Public (unauthenticated) discovery document. # List the agents exposed over A2A Source: https://docs.landfall.ai/api-reference/a2a/list-the-agents-exposed-over-a2a /api-reference/openapi.yml get /a2a Convenience listing of the available A2A agents and their AgentCard URLs. Public, no authentication. # Delete an agent run and any resume cache associated with it Source: https://docs.landfall.ai/api-reference/agentruns/delete-an-agent-run-and-any-resume-cache-associated-with-it /api-reference/openapi.yml delete /query/runs/{runId} Permanently removes the run record and its checkpoint blob. Returns 404 for both "never existed" and "owned by someone else" to avoid leaking existence of other users' conversations. # Get the status of an agent run Source: https://docs.landfall.ai/api-reference/agentruns/get-the-status-of-an-agent-run /api-reference/openapi.yml get /query/runs/{runId} Returns the current status of an agent run, the original question, and (for completed runs) the rendered result. Use this to discover whether a run is still running, completed, failed, or expired (e.g. after a dropped SSE connection). # Resume a previously paused or crashed agent run Source: https://docs.landfall.ai/api-reference/agentruns/resume-a-previously-paused-or-crashed-agent-run /api-reference/openapi.yml post /query/runs/{runId}/resume Resumes a run from its last checkpoint. The response is an SSE stream whose first event is `run-started`, followed by the same domain events as the original streaming endpoint (e.g. `plan`, `step`, `answer` for AutoRag). Concurrency: each call rotates the run's session id. If a second resume request arrives while a first is in flight, the first wrapper exits silently on its next checkpoint write; only the latest resume continues streaming events to its caller. Only runs whose agent checkpoints its progress can be replayed. The AutoRag agent currently writes no checkpoints, so resume answers 409 for every run still in progress and the run continues to completion on its original connection. Terminal states are surfaced via HTTP status codes: - 410 Gone: run is Completed (the final answer is in the body) OR Expired (its resume cache is gone or no longer loadable). The body carries the original question and, for Completed runs, the rendered result. - 409 Conflict: run has no checkpoint to replay from. It is left untouched — poll `GET /api/v1/query/runs/{runId}` for its outcome. - 422 Unprocessable Content: run is in a Failed state - 404 Not Found: run does not exist or is not owned by the caller # Submit thumbs up/down feedback on a completed agent run Source: https://docs.landfall.ai/api-reference/agentruns/submit-thumbs-updown-feedback-on-a-completed-agent-run /api-reference/openapi.yml post /query/runs/{runId}/feedback Records user feedback (thumbs up/down plus an optional comment) as a score on the Langfuse trace that produced the run's answer. Only completed runs can be rated. Resubmitting overwrites the previous feedback for the same run. # Get code files for a cleaning task Source: https://docs.landfall.ai/api-reference/agents/get-code-files-for-a-cleaning-task /api-reference/openapi.yml get /agents/cleaning/{cleaningTaskId}/code Retrieve metadata for all code files generated by the cleaning agent for the specified task. # Request cleaning on a dataset Source: https://docs.landfall.ai/api-reference/agents/request-cleaning-on-a-dataset /api-reference/openapi.yml post /agents/{username}/{namespace}/{datasetName}/requestCleaning Request a cleaning job for the specified dataset. # Run AutoRAG agent over all data Source: https://docs.landfall.ai/api-reference/autorag/run-autorag-agent-over-all-data /api-reference/openapi.yml post /query/autorag Uses the AutoRAG agent to answer a question about any data that the user can access. # Run AutoRAG agent with streaming response Source: https://docs.landfall.ai/api-reference/autorag/run-autorag-agent-with-streaming-response /api-reference/openapi.yml post /query/ask Uses the AutoRAG agent to answer a question about any data that the user can access. Returns results as a Server-Sent Events (SSE) stream with incremental updates. The stream emits the following event types in order: - `plan`: The execution plan with a list of steps to be performed. - `step`: One event per step, containing the instruction, query, and result data. - `answer`: The final synthesized answer to the user's question. - `error`: Emitted if an error occurs during processing (instead of answer). # Add a file to a batch file-input slot Source: https://docs.landfall.ai/api-reference/buildspecs/add-a-file-to-a-batch-file-input-slot /api-reference/openapi.yml post /build-specs/{buildSpecId}/file-inputs/{slot}/members Adds one uploaded file to the slot's bound set (for batch slots). # Create a BuildSpec Source: https://docs.landfall.ai/api-reference/buildspecs/create-a-buildspec /api-reference/openapi.yml post /build-specs Create a derived-dataset transformation definition. Datasets are addressed by user/namespace/dataset name. The caller must have access to every source and every destination. # Delete a BuildSpec Source: https://docs.landfall.ai/api-reference/buildspecs/delete-a-buildspec /api-reference/openapi.yml delete /build-specs/{buildSpecId} # Edit a BuildSpec Source: https://docs.landfall.ai/api-reference/buildspecs/edit-a-buildspec /api-reference/openapi.yml put /build-specs/{buildSpecId} Replace the definition and bump its version. Datasets are addressed by name. # Fetch a preview output's download URL Source: https://docs.landfall.ai/api-reference/buildspecs/fetch-a-preview-outputs-download-url /api-reference/openapi.yml get /build-runs/{buildRunId}/outputs/{destinationName} Returns a time-limited presigned S3 URL to download one destination slot's produced rows (JSONL) directly from the bucket. Only available for preview runs. # Get a BuildRun Source: https://docs.landfall.ai/api-reference/buildspecs/get-a-buildrun /api-reference/openapi.yml get /build-runs/{buildRunId} # Get a BuildSpec Source: https://docs.landfall.ai/api-reference/buildspecs/get-a-buildspec /api-reference/openapi.yml get /build-specs/{buildSpecId} # List a BuildSpec's runs Source: https://docs.landfall.ai/api-reference/buildspecs/list-a-buildspecs-runs /api-reference/openapi.yml get /build-specs/{buildSpecId}/runs # List a pipeline repo's files Source: https://docs.landfall.ai/api-reference/buildspecs/list-a-pipeline-repos-files /api-reference/openapi.yml get /build-specs/{buildSpecId}/files The paths of every file in the GitPipeline repo at the default branch's HEAD. # List a pipeline's file-input slot bindings Source: https://docs.landfall.ai/api-reference/buildspecs/list-a-pipelines-file-input-slot-bindings /api-reference/openapi.yml get /build-specs/{buildSpecId}/file-inputs The uploaded files currently bound to each file-input slot of a GitPipeline BuildSpec. # List a preview run's outputs Source: https://docs.landfall.ai/api-reference/buildspecs/list-a-preview-runs-outputs /api-reference/openapi.yml get /build-runs/{buildRunId}/outputs A code-blob preview returns one entry per destination slot (each with an href to fetch its download URL). A GitPipeline preview returns every produced output (declared, computed and discovered), each with an inline presigned download URL. Only available for preview runs. # List the caller's BuildSpecs Source: https://docs.landfall.ai/api-reference/buildspecs/list-the-callers-buildspecs /api-reference/openapi.yml get /build-specs Returns every BuildSpec owned by the authenticated user. # Preview a build (dry run) Source: https://docs.landfall.ai/api-reference/buildspecs/preview-a-build-dry-run /api-reference/openapi.yml post /build-specs/{buildSpecId}/preview Run the BuildSpec against a small sample of each source (capped at 100 rows) and present the output to the caller WITHOUT ingesting it into any dataset. Requires read (QUERY) access to the sources and destination datasets. The saved code may be overridden with inline code for this preview. At most one preview may be active per spec. Returns the new run in status `Scheduled`; poll the run and then fetch its outputs once it reaches `Finished`. # Read one file from a pipeline repo Source: https://docs.landfall.ai/api-reference/buildspecs/read-one-file-from-a-pipeline-repo /api-reference/openapi.yml get /build-specs/{buildSpecId}/file The content and commit sha of a single file at the default branch's HEAD. # Remove a file from a file-input slot Source: https://docs.landfall.ai/api-reference/buildspecs/remove-a-file-from-a-file-input-slot /api-reference/openapi.yml delete /build-specs/{buildSpecId}/file-inputs/{slot}/members/{fileId} Removes one uploaded file from the slot's bound set. # Save edits to a pipeline repo Source: https://docs.landfall.ai/api-reference/buildspecs/save-edits-to-a-pipeline-repo /api-reference/openapi.yml put /build-specs/{buildSpecId}/files Commits an atomic set of file upserts and deletions to the default branch. Carries the base commit sha for optimistic concurrency; a stale base is rejected with 409. `.dvc/config` is platform-owned and cannot be written or deleted. # Schedule a build (create a BuildRun) Source: https://docs.landfall.ai/api-reference/buildspecs/schedule-a-build-create-a-buildrun /api-reference/openapi.yml post /build-specs/{buildSpecId}/run Schedule a build of the BuildSpec. Re-checks the caller's access to the spec's datasets and rejects the request if the spec already has an active run. Returns the new run in status `scheduled`. # Set (replace) the files bound to a file-input slot Source: https://docs.landfall.ai/api-reference/buildspecs/set-replace-the-files-bound-to-a-file-input-slot /api-reference/openapi.yml put /build-specs/{buildSpecId}/file-inputs/{slot} Replaces the slot's bound files with the given set. An empty set unbinds the slot. # Unbind a file-input slot Source: https://docs.landfall.ai/api-reference/buildspecs/unbind-a-file-input-slot /api-reference/openapi.yml delete /build-specs/{buildSpecId}/file-inputs/{slot} Removes all files bound to the slot. # Validate a pipeline repo Source: https://docs.landfall.ai/api-reference/buildspecs/validate-a-pipeline-repo /api-reference/openapi.yml post /build-specs/{buildSpecId}/files/validate Runs advisory checks on the repo at HEAD (dvc.yaml present, manifests parse, sources reconcile). Advisory only; it never blocks saving. # Get a conversation and its turns Source: https://docs.landfall.ai/api-reference/conversations/get-a-conversation-and-its-turns /api-reference/openapi.yml get /query/conversations/{conversationId} Returns the conversation's turns (oldest first), each with the original question, its status, and — for completed turns — the rendered result. Returns 404 for both "never existed" and "owned by someone else" to avoid leaking existence of other users' conversations. # List the caller's conversations within a namespace Source: https://docs.landfall.ai/api-reference/conversations/list-the-callers-conversations-within-a-namespace /api-reference/openapi.yml get /query/conversations Returns the caller's conversations in the given namespace, most-recently-updated first. A conversation groups the agent runs (turns) the user sees as a single thread. # List ingestions for a dataset Source: https://docs.landfall.ai/api-reference/data/list-ingestions-for-a-dataset /api-reference/openapi.yml get /data/{username}/{namespace}/{datasetName}/ingest/attempts Lists ingestion attempts for a dataset. # Clear all data for a dataset Source: https://docs.landfall.ai/api-reference/dataset/clear-all-data-for-a-dataset /api-reference/openapi.yml post /data/{username}/{namespace}/{datasetName}/clear Remove all data and links from the specified dataset. This action is irreversible. # Delete all data and metadata for a dataset (balefire) Source: https://docs.landfall.ai/api-reference/dataset/delete-all-data-and-metadata-for-a-dataset-balefire /api-reference/openapi.yml delete /data/{username}/{namespace}/{datasetName}/balefire Remove all data, links, and metadata for the specified dataset. This action is irreversible. # Get dataset information Source: https://docs.landfall.ai/api-reference/dataset/get-dataset-information /api-reference/openapi.yml get /data/{username}/{namespace}/{datasetName} Get dataset metadata for the specified user, namespace, and dataset. # Rename a dataset Source: https://docs.landfall.ai/api-reference/dataset/rename-a-dataset /api-reference/openapi.yml post /data/{username}/{namespace}/{datasetName}/rename Rename the specified dataset. # Rename a namespace Source: https://docs.landfall.ai/api-reference/dataset/rename-a-namespace /api-reference/openapi.yml post /data/{username}/{namespace}/rename Rename the specified namespace. # Update dataset sort order Source: https://docs.landfall.ai/api-reference/dataset/update-dataset-sort-order /api-reference/openapi.yml put /schema/{username}/{namespace}/{datasetName}/sort-order Update the sort order of columns in a dataset. # Update inference definition Source: https://docs.landfall.ai/api-reference/dataset/update-inference-definition /api-reference/openapi.yml put /data/{username}/{namespace}/{datasetName}/inferDefinition Update the saved inference definition for the dataset. # Fetch datasets Source: https://docs.landfall.ai/api-reference/datasets/fetch-datasets /api-reference/openapi.yml get /data Retrieve all available datasets. # Fetch datasets in namespace Source: https://docs.landfall.ai/api-reference/datasets/fetch-datasets-in-namespace /api-reference/openapi.yml get /data/{namespace} Retrieve all datasets for the specified namespace. # Abort file upload Source: https://docs.landfall.ai/api-reference/fileupload/abort-file-upload /api-reference/openapi.yml post /file-upload/{sessionId}/abort Abort a single file upload # Finish file upload Source: https://docs.landfall.ai/api-reference/fileupload/finish-file-upload /api-reference/openapi.yml post /file-upload/{sessionId}/files/{fileId}/finish Finish a single file upload # List completed files in an upload session Source: https://docs.landfall.ai/api-reference/fileupload/list-completed-files-in-an-upload-session /api-reference/openapi.yml get /file-upload/{sessionId}/files Returns S3 bucket and key for every completed file in the session. Caller must own the session. # Prepare session for file upload Source: https://docs.landfall.ai/api-reference/fileupload/prepare-session-for-file-upload /api-reference/openapi.yml post /file-upload/prepare Initiate a file upload session and get the upload URLs. # API Reference Source: https://docs.landfall.ai/api-reference/index Welcome to the DataLinks API. These endpoints let you bring in data, connect it intelligently, and ask questions that yield grounded results. Expand any group in the left navigation to view its endpoints. Some endpoints require a `username` for authorization. The easiest way to verify your account `username` is to open a dataset in the web platform and inspect the URL slug. For example, `https://datalinks.com/dashboard/USERNAME/testing/testing123` ## Typical end-to-end flow 1. **Create a dataset**\ Use Create new dataset. Supplying a new namespace creates it implicitly. `POST` [Create new dataset](/api-reference/ingest/create-new-dataset) 2. **Ingest data**\ Use Ingest data or the multipart flow for large files. Use Preview to check parsing before committing. `POST` [Ingest data](/api-reference/ingest/ingest-data)\ `POST` [Preview](/api-reference/ingest/preview) Multipart flow:\ `POST` [Prepare multipart upload](/api-reference/multipart-upload/prepare-multipart-upload)\ `POST` [Finish multipart upload](/api-reference/multipart-upload/finish-multipart-upload)\ `POST` [Abort multipart upload](/api-reference/multipart-upload/abort-multipart-upload) 3. **Review links**\ Use Load links and Preview links. Promote useful suggestions to active links with Add a new link or from the app UI. Rebuild links when data changes. `GET` [Load links](/api-reference/links/load-links)\ `POST` [Preview links](/api-reference/links/preview-links)\ `POST` [Add a new link](/api-reference/links/add-a-new-link)\ `POST` [Rebuild links](/api-reference/links/rebuild-links) 4. **Query**\ Use Query data to retrieve grounded results across connected datasets. `POST` [Query data](/api-reference/query/query-data) ## Notes and best practices * **Namespaces**: a namespace appears when you create the first dataset that references it. * **Large files**: prefer the multipart upload trio to improve reliability. * **Performance**: Rebuild links after large ingests so suggestions reflect the latest data. If you're looking for background to get started, see the explanatory articles for [Ingest](/concepts/ingest-clean), [Interconnect](/concepts/interconnection), and [Inquire](/concepts/query-insights), then return here to try automating those steps using the API. # Create new dataset Source: https://docs.landfall.ai/api-reference/ingest/create-new-dataset /api-reference/openapi.yml post /ingest/new/{namespace}/{datasetName} Creates a new dataset within a specified namespace. # Infer dataset description Source: https://docs.landfall.ai/api-reference/ingest/infer-dataset-description /api-reference/openapi.yml post /infer/description Ask an agent to infer a data description based on sampled data. # Ingest data Source: https://docs.landfall.ai/api-reference/ingest/ingest-data /api-reference/openapi.yml post /ingest/{namespace}/{datasetName} Load data into the specified dataset. # Preview Source: https://docs.landfall.ai/api-reference/ingest/preview /api-reference/openapi.yml post /infer/preview Process data using ingestion logic without saving it to a dataset. # Schema Source: https://docs.landfall.ai/api-reference/ingest/schema /api-reference/openapi.yml post /infer/schema Ask an agent to infer a schema based on sampled data. # Mark ingestion as seen Source: https://docs.landfall.ai/api-reference/ingestiontracking/mark-ingestion-as-seen /api-reference/openapi.yml post /ingestionTracking/{ingestionId}/seen Update seenAt timestamp for the specified ingestion. # Retry ingestion Source: https://docs.landfall.ai/api-reference/ingestiontracking/retry-ingestion /api-reference/openapi.yml post /ingestionTracking/{ingestionId}/retry Creates a new ingestion record copying data from the original and starts the ingestion process in the background. Returns the new ingestion ID. # Add a new link Source: https://docs.landfall.ai/api-reference/links/add-a-new-link /api-reference/openapi.yml post /links/add Create a new link between two dataset columns. # Load links Source: https://docs.landfall.ai/api-reference/links/load-links /api-reference/openapi.yml get /links/{username}/{namespace}/{datasetName} Load the links for the specified dataset. # Preview links Source: https://docs.landfall.ai/api-reference/links/preview-links /api-reference/openapi.yml post /links/preview/{username}/{namespace}/{datasetName} Shows what recalculating links would look like without saving changes. # Rebuild links Source: https://docs.landfall.ai/api-reference/links/rebuild-links /api-reference/openapi.yml post /links/{username}/{namespace}/{datasetName} Recalculate links for a specified dataset. # Abort multipart upload Source: https://docs.landfall.ai/api-reference/multipart-upload/abort-multipart-upload /api-reference/openapi.yml post /upload/multipart/{username}/{namespace}/{datasetName}/abort Abort a multipart upload and clean up partial data. # Finish multipart upload Source: https://docs.landfall.ai/api-reference/multipart-upload/finish-multipart-upload /api-reference/openapi.yml post /upload/multipart/{username}/{namespace}/{datasetName}/finish Finish a multipart upload by providing all part ETags. # Prepare multipart upload Source: https://docs.landfall.ai/api-reference/multipart-upload/prepare-multipart-upload /api-reference/openapi.yml post /upload/multipart/{username}/{namespace}/{datasetName}/prepare Initiate a multipart upload and get presigned URLs for all parts. # Delete all data and metadata for a namespace (balefire) Source: https://docs.landfall.ai/api-reference/namespace/delete-all-data-and-metadata-for-a-namespace-balefire /api-reference/openapi.yml delete /data/{username}/{namespace}/balefire Remove all data, links, and metadata for the specified namespace. This action is irreversible. Can remove dataset if flag 'deleteDatasets' is set to true # Curate ontology links Source: https://docs.landfall.ai/api-reference/ontology/curate-ontology-links /api-reference/openapi.yml post /ontology/curate-links Run the OntologyCurator agent to analyze computed links for a dataset or all datasets in a namespace. When activate is true, the curated links are added to the ontology. When activate is false (default), only returns the curated links without activating them. # Get dataset ontology Source: https://docs.landfall.ai/api-reference/ontology/get-dataset-ontology /api-reference/openapi.yml get /ontology/{username}/{namespace}/{datasetName} Load the ontology for the specified dataset. # Save dataset ontology Source: https://docs.landfall.ai/api-reference/ontology/save-dataset-ontology /api-reference/openapi.yml post /ontology/{username}/{namespace}/{datasetName} Save the ontology for the specified dataset. # List users with access to a dataset Source: https://docs.landfall.ai/api-reference/permissions/list-users-with-access-to-a-dataset /api-reference/openapi.yml get /permissions/datasets/{username}/{namespace}/{datasetName}/shares List the per-user grants on a dataset. Only the dataset owner may list. # List users with access to a namespace Source: https://docs.landfall.ai/api-reference/permissions/list-users-with-access-to-a-namespace /api-reference/openapi.yml get /permissions/namespaces/{username}/{namespace}/shares List the per-user grants on a namespace. Only the namespace owner may list. # Revoke a user's access to a dataset Source: https://docs.landfall.ai/api-reference/permissions/revoke-a-users-access-to-a-dataset /api-reference/openapi.yml delete /permissions/datasets/{username}/{namespace}/{datasetName}/shares Remove a previously granted viewer or editor access from a user. Only the dataset owner may revoke. # Revoke a user's access to a namespace Source: https://docs.landfall.ai/api-reference/permissions/revoke-a-users-access-to-a-namespace /api-reference/openapi.yml delete /permissions/namespaces/{username}/{namespace}/shares Remove a previously granted viewer or editor access from a user. Only the namespace owner may revoke. # Share a dataset with a user Source: https://docs.landfall.ai/api-reference/permissions/share-a-dataset-with-a-user /api-reference/openapi.yml post /permissions/datasets/{username}/{namespace}/{datasetName}/shares Grant another user viewer or editor access to a dataset. Only the dataset owner may share. # Share a namespace with a user Source: https://docs.landfall.ai/api-reference/permissions/share-a-namespace-with-a-user /api-reference/openapi.yml post /permissions/namespaces/{username}/{namespace}/shares Grant another user viewer or editor access to a namespace. The grant cascades to all datasets within the namespace. Only the namespace owner may share. # Query data Source: https://docs.landfall.ai/api-reference/query/query-data /api-reference/openapi.yml post /query Execute an ontology query. # List all datasets Source: https://docs.landfall.ai/api-reference/schema/list-all-datasets /api-reference/openapi.yml get /schema/datasets/all Retrieve all datasets visible to the authenticated user. # List datasets within namespace Source: https://docs.landfall.ai/api-reference/schema/list-datasets-within-namespace /api-reference/openapi.yml get /schema/{user}/{namespace}/datasets Retrieve datasets within a specific namespace for a user. Use 'self' for the current user. # List user namespaces Source: https://docs.landfall.ai/api-reference/schema/list-user-namespaces /api-reference/openapi.yml get /schema/{user}/namespaces Retrieve namespaces for a specific user. Use 'self' for the current user. # Add a new user token Source: https://docs.landfall.ai/api-reference/user/add-a-new-user-token /api-reference/openapi.yml post /user/token Create a new token for the authenticated user. # Delete user token Source: https://docs.landfall.ai/api-reference/user/delete-user-token /api-reference/openapi.yml delete /user/token/{tokenId} Delete the specified user token. # Get the current user Source: https://docs.landfall.ai/api-reference/user/get-the-current-user /api-reference/openapi.yml get /user/me Returns the identity of the authenticated user resolved from the presented bearer token. # Get user usage aggregated by day Source: https://docs.landfall.ai/api-reference/user/get-user-usage-aggregated-by-day /api-reference/openapi.yml get /user/usage/by-day Retrieve usage data aggregated by day for the authenticated user, with timezone support. # Get user usage history Source: https://docs.landfall.ai/api-reference/user/get-user-usage-history /api-reference/openapi.yml get /user/usage/history Retrieve historical usage data for the authenticated user. # List token permissions Source: https://docs.landfall.ai/api-reference/user/list-token-permissions /api-reference/openapi.yml get /user/tokens/{tokenId}/permissions List all permissions assigned to the specified token. # List user tokens Source: https://docs.landfall.ai/api-reference/user/list-user-tokens /api-reference/openapi.yml get /user/tokens List all tokens for the authenticated user. # Datasets and Namespaces Source: https://docs.landfall.ai/concepts/datasets-namespaces In DataLinks, all information lives within a simple and flexible structure built around **namespaces** and **datasets**. Together, they organize your data, define ownership, and make it easier to manage access and relationships across the platform. Understanding how namespaces and datasets fit together is the first step in working effectively with DataLinks, whether you use the web platform or the API. ## What a namespace is A namespace is a logical container that groups datasets under a shared context. It defines *who* the data belongs to and *where* it lives inside your workspace. You can think of a namespace as the digital equivalent of a project or folder. Each user can have multiple namespaces. Within them, datasets can be organized by department, use case, or business function. Namespaces are also used to manage access and visibility. A dataset in a private namespace is visible only to its owner or designated users, while a dataset in a public namespace can be viewed and connected to by anyone on the DataLinks platform. Namespaces can be listed and reviewed using the API: * [GET List user namespaces](/api-reference/schema/list-user-namespaces) * [GET List datasets within namespace](/api-reference/schema/list-datasets-within-namespace) ## What a dataset is A dataset is a structured collection of data stored within a namespace. It can contain information that was ingested from a file, a database export, an API feed, or even unstructured text that has been cleaned and structured by DataLinks. Every dataset has: * A dataset **name** (unique within its namespace) * A **namespace** that the dataset sits in * A **visibility level** (private or public) Datasets are the foundation of all downstream actions in DataLinks. They feed the linking process that connects related information, and they serve as the building blocks for AI-driven queries. When using the API, you can view and manage datasets using: * [GET Fetch datasets](/api-reference/datasets/fetch-datasets) * [GET Fetch datasets in namespace](/api-reference/datasets/fetch-datasets-in-namespace?utm_source=chatgpt.com) * [GET Get dataset information](/api-reference/dataset/get-dataset-information) ## How namespaces and datasets work together Namespaces organize datasets, and datasets give structure to the data itself. When you create a dataset, you must specify which namespace it belongs to. This ensures that ownership, permissions, and context are always clear. A single namespace might contain several datasets, for example, `finance_revenue`, `finance_expenses`, and `finance_forecasts`. Namespaces prevent naming conflicts between teams while allowing easy sharing across a shared environment. They also make it possible to apply consistent access controls and data governance rules. ## Creating namespaces and datasets You can create and manage both namespaces and datasets through the web platform or using the API. For step-by-step instructions, see [How To Create a Namespace](/how-to/create-namespace) and [How To Create a Dataset](/how-to/create-dataset). ### Using the web platform The DataLinks web platform provides a visual interface for creating namespaces and datasets. From the dashboard, you can: * Create a new namespace and set its visibility * Add datasets within that namespace * Upload data files directly or start ingestion through the interface This method is ideal for quick setup or when you want to explore data interactively. ### Using the API For automated workflows or large-scale operations, the DataLinks API is the preferred option. The key endpoints include: * [POST Create new dataset](/api-reference/ingest/create-new-dataset) * [POST Ingest data](/api-reference/ingest/ingest-data) * [POST Preview](/api-reference/ingest/preview) * [POST Rename a dataset](/api-reference/dataset/rename-a-dataset) * [PUT Update infer definition](/api-reference/dataset/update-infer-definition) When you create a dataset through the API, you specify the target namespace in the request. Once the dataset exists, you can ingest data directly into it, preview results, or adjust its structure programmatically. ## Managing and maintaining your structure Over time, you may need to adjust your namespace and dataset configuration. The following endpoints support maintenance and cleanup: * [PUT Update dataset sort order](/api-reference/dataset/update-dataset-sort-order) * [POST Clear all data for a dataset](/api-reference/dataset/clear-all-data-for-a-dataset) * [DEL Delete all data and metadata for a dataset (balefire)](/api-reference/dataset/delete-all-data-and-metadata-for-a-dataset-balefire) These ensure your workspace stays organized and that older or redundant data can be removed safely without affecting other namespaces. ## Why namespaces and datasets matter Namespaces and datasets bring clarity to complex data environments. They provide consistent organization, clear ownership, and a path for controlled sharing. Whether you use the web platform for simplicity or the API for scale, namespaces and datasets are the foundation for everything that happens in DataLinks, from ingestion to interconnection to inquiry. # Data Ingestion and Cleaning Source: https://docs.landfall.ai/concepts/ingest-clean Organizations of all sizes are seeing their data grow faster than their ability to use it, with much of that data living in spreadsheets, databases, PDFs, emails, and countless other siloed sources. Yet when businesses try to apply it to AI or automation, the results disappoint. The reason is simple: the data exists, but it is messy, inconsistent, and disconnected. At DataLinks, ingestion and cleaning are not viewed as separate chores. They are seen as the first stages of intelligence. Together, they transform unstructured or disconnected information into structured, standardized data that can be understood by people and by AI systems. ## Why traditional ingestion and cleaning fall short In most environments, ingestion simply means collecting data from one place and storing it in another. Cleaning is handled later, usually through manual scripts that remove errors, rename columns, or standardize formats. These steps are repetitive and lack an understanding of the data being ingested. Even after cleaning, the result can be technically correct but still inconsistent. A company name might appear in several different forms, or a date field might use mixed formats. When this happens, relationships between datasets are hidden, and insights are lost. Treating ingestion and cleaning as separate stages causes delay and duplication. Teams spend time fixing the same problems in slightly different ways, and valuable information remains disconnected. ## Using the DataLinks web platform or the API DataLinks offers two ways to ingest and clean data: through the web platform or through the API. Both use the same underlying infrastructure and produce identical results, but each suits a different kind of workflow. ### The web platform The DataLinks web platform is the fastest way to start. It provides a guided experience for creating datasets, uploading files, and running ingestion directly from your browser. You can preview data, apply cleaning options via prompts, and view validation results in real time. This interface is ideal when: * You are testing new data sources or experimenting with formats * You want to see immediate visual feedback on how cleaning and extraction work * You are working with a limited number of files or moderate data volumes The platform automatically applies the same cleaning, validation, and normalization logic used by the API. It also records metadata so your results stay consistent if you later decide to automate ingestion. ### The DataLinks API For larger or recurring workloads, the DataLinks API is the best choice. The API provides endpoints for every step in the ingestion and cleaning process, from creating datasets and previewing files to ingesting, validating, and managing them at scale. This approach is best when: * You need to ingest large or frequent data uploads * You want to integrate DataLinks with an existing data pipeline or workflow * You prefer automation over manual uploads * You are handling high-volume or sensitive datasets where precision and repeatability matter The API supports multipart uploads and asynchronous processing for efficiency. ## How DataLinks improves ingestion and cleaning DataLinks combines ingestion, cleaning, and validation so that every dataset is structured correctly from the beginning. The process uses a simple sequence of API calls, all of which are available in the DataLinks API documentation. ### Step 1. Create a dataset The ingestion process begins by defining where data will live. You use the **Create new dataset** endpoint ([POST Create new dataset](/api-reference/ingest/create-new-dataset)) to register a dataset within a namespace. This step establishes ownership, visibility, and a consistent place for data to be ingested. You can review existing datasets or namespaces using: * [GET Fetch datasets](/api-reference/datasets/fetch-datasets) * [GET Fetch datasets in namespace](/api-reference/datasets/fetch-datasets-in-namespace?utm_source=chatgpt.com) * [GET List all datasets](/api-reference/schema/list-all-datasets) * [GET List user namespaces](/api-reference/schema/list-user-namespaces) * [GET List datasets within namespace](/api-reference/schema/list-datasets-within-namespace) These endpoints ensure teams know exactly where each dataset lives before ingestion begins. ### Step 2. Preview your data Before uploading large or complex files, you can use the [POST Preview](/api-reference/ingest/preview) endpoint to inspect a sample. This confirms that fields, headers, and formats look correct before the full load. If data requires cleaning instructions, you can add prompts or definitions at this stage. For example, you might request that all dates be standardized or that field names follow a specific convention. ### Step 3. Ingest and clean data Once the dataset and preview look correct, use the [POST Ingest data](/api-reference/ingest/ingest-data) endpoint to bring data into the platform. During ingestion, DataLinks automatically: * Extracts structure from both structured and unstructured inputs * Applies normalization to align fields to the target schema * Flags missing or mismatched values * Validates that data fits expected patterns ### Step 4. Review and manage datasets Once data is ingested, it can be inspected and maintained through several dataset-level APIs: * [GET Get dataset information](/api-reference/dataset/get-dataset-information) Retrieves full metadata, including owner, namespace, and visibility. * [POST Rename a dataset](/api-reference/dataset/rename-a-dataset) Updates dataset names without recreating them. If cleaning requires a full reset, two endpoints handle dataset clearing or deletion: * [POST Clear all data for a dataset](/api-reference/dataset/clear-all-data-for-a-dataset) Empties a dataset while keeping its metadata. * [DEL Delete all data and metadata for a dataset (balefire)](/api-reference/dataset/delete-all-data-and-metadata-for-a-dataset-balefire) Completely removes a dataset and its associated records. ### Step 5. Maintain structure and relationships While link creation and ontology management are covered in later articles, ingestion depends on their foundations. For reference, related endpoints include: * [GET Load links](/api-reference/links/load-links) * [POST Rebuild links](/api-reference/links/rebuild-links) * [POST Preview links](/api-reference/links/preview-links) * [POST Add a new link](/api-reference/links/add-a-new-link) * [GET Get ontology](/api-reference/ontology/get-ontology-) * [POST Post ontology](/api-reference/ontology/post-ontology-) These interfaces are how ingested and cleaned data later become connected and semantically rich. ### Step 6. Authentication and tokens All API operations use token-based authentication. Tokens are managed through: * [GET Get usertokens](/api-reference/user/get-usertokens) * [POST Post usertoken](/api-reference/user/post-usertoken) * [DEL Delete usertoken](/api-reference/user/delete-usertoken) These endpoints allow secure access while keeping control in the hands of dataset owners. ## Why this matters AI systems and analytics tools depend on consistent data. If data arrives in different shapes, or if key fields vary from file to file, even the best models will produce uncertain results. By combining ingestion and cleaning, DataLinks ensures that data is immediately usable. Clean structure, standardized labels, and reliable formatting make it easier to connect information later and to build accurate insights. This process also reduces the time and technical skill needed to prepare data. Instead of spending weeks building scripts, teams can upload data, add simple cleaning instructions, and trust the output. ## Example scenarios * **Financial data**: Normalize columns and clean date formats before analysis to ensure accuracy across multiple reports. * **Procurement data**: Ingest vendor lists from different departments, fix naming inconsistencies, and prepare them for future linking. * **Unstructured reports**: Convert raw text into structured rows, apply date formatting, and validate results automatically. Each of these cases shows how intelligent ingestion removes repetitive cleanup and gives teams data they can use immediately. ## The foundation for what comes next Ingestion and cleaning form the first phase of the broader DataLinks model: **Ingest, Interconnect, Inquire.** * Ingest prepares and cleans the data. * Interconnect builds relationships between datasets. * Inquire allows people and AI to explore the results. Without clean, consistent ingestion, the rest of the process cannot succeed. Ingestion and cleaning is where raw information first starts to become meaningful. # Interconnection (Knowledge Maps) Source: https://docs.landfall.ai/concepts/interconnection Once your data is ingested and organized into datasets, DataLinks automatically begins to find relationships between them. This process is known as **interconnection**, and it is the foundation of what makes DataLinks a true ontological system rather than just another data warehouse. ## From datasets to knowledge maps Each dataset in DataLinks represents a collection of related facts, such as a registry of companies, a list of shareholders, or a table of tariffs. When multiple datasets exist within the same private namespace, or across public namespaces, DataLinks can detect and create **links** between them based on shared entities such as company names, IDs, or other attributes. These relationships form a **knowledge map**: a living network of data that shows how your information connects across different contexts. The screenshot above is an example of this visualization in the DataLinks web platform. On the left, you can see datasets represented as nodes, with active links connecting them. On the right, you see the list of **Suggested links** and **Active links:** the relationships that have been automatically discovered or confirmed. ## Why interconnection matters Most organizations struggle not because they lack data, but because their data lives in silos. Each dataset tells part of the story, but the real value emerges only when those pieces connect. Interconnection turns data into context. It allows DataLinks to: * Surface hidden relationships between entities * Enrich AI and analytics with broader context * Enable complex reasoning across datasets, such as tracing ownership networks or identifying risk exposure This connected structure also provides the semantic memory that makes AI agents intelligent and consistent. When data is linked through knowledge maps, AI systems can recall facts, understand context, and reason across multiple domains, just like a human analyst. ## How it works When a dataset is connected to others, the platform performs entity matching and link inference using both rule-based logic and AI-assisted reasoning. It identifies similar fields, overlapping records, and meaningful associations that may not be obvious in the raw data. For instance: * A registry/companies dataset might connect to registry/shareholders through shared company IDs or names. * The same company could also link to sanctions/individuals or supply chain/tariffs datasets if related entities are detected. * Each connection is scored, labeled (for example, “exact match” or “partial match”), and stored for reuse across the platform. This linking process can be managed through the web platform or the API: * [GET Load links](/api-reference/links/load-links) * [POST Add a new link](/api-reference/links/add-a-new-link) * [POST Rebuild links](/api-reference/links/rebuild-links) * [POST Preview links](/api-reference/links/preview-links) Through these endpoints, developers can programmatically create, rebuild, or preview connections, making it possible to automate updates as new data is ingested. ## Visualizing connections The DataLinks web platform provides an interactive **Connections** view where each node represents a dataset and each line represents an active or potential link. Hovering over a node reveals its relationships, and clicking a link shows the fields or entities involved. This visualization helps users explore data relationships intuitively, trace where insights come from, and understand how their information fits within the wider enterprise knowledge map. # Querying Data and Insights Source: https://docs.landfall.ai/concepts/query-insights Once data is ingested and cleaned, then connected into knowledge maps, the next step is understanding it. Querying is how users turn structured data into clear, actionable insights. In traditional systems, querying requires technical skill and a precise knowledge of where data lives. At DataLinks, this process is transformed. The platform combines the power of structured data with the reasoning ability of large language models (LLMs) so that anyone can ask questions and get accurate, meaningful answers. ## From data to questions Most enterprise data is too complex for manual exploration. Each table might contain thousands of rows, dozens of columns, and connections across multiple datasets. Writing SQL to join and filter all of that is time-consuming and error-prone. DataLinks bridges that gap by using LLMs to interpret questions and generate the right structure automatically. When a user types a question, for example, *“Show me all suppliers who serve both our European and Asian operations”* , the system translates that intent into an optimized SQL query that runs across the connected datasets. This is not just keyword matching. The model understands context, recognizes relevant entities, and uses the knowledge map to locate the necessary tables and fields. It can reason about relationships such as *companies → shareholders → regions* and construct multi-step queries that would otherwise require a data analyst. ## How querying works in DataLinks Querying is built into both the **web platform** and the **API**, giving flexibility to business users, analysts, and developers alike. 1. **Web Platform** Through the Preview & Query interface, users can type natural language prompts or manually write SQL. The platform runs the query, displays results, and highlights the underlying datasets and links used. 2. **API** Developers can submit queries directly using: * [POST Query data](/api-reference/query/query-data) This endpoint accepts structured query requests and returns results as JSON, which can be integrated into dashboards, reports, or applications. ## The role of the LLM in structuring queries At the core of DataLinks' querying is the LLM-powered reasoning engine. Its role is not to replace databases but to make them more accessible and intelligent. Unlike generic chat-based LLM systems that generate freeform answers, DataLinks uses its models to reason *within* the boundaries of verified enterprise data. Every answer is grounded in facts that come directly from your connected datasets. Here is how the process works: * **Interpretation:** The model reads your natural language question and identifies the relevant entities and metrics. * **Translation:** It converts that intent into query syntax, joining the correct datasets within the namespace. * **Optimization:** It selects the most efficient path through the knowledge map, prioritizing the strongest or most relevant links. ### How hallucinations are mitigated Because the LLM operates on top of DataLinks’ structured semantic layer, it cannot produce results outside of what the data actually contains. The model does not “guess” or fill in gaps. Instead, it constructs queries that are executed against real, verified data. This design eliminates the most common cause of hallucination in AI-driven analytics: freeform generation without grounding. The system ensures reliability in several ways: * **Grounded reasoning:** The model only references information that exists in connected datasets. * **Schema awareness:** It understands dataset structure and field names, which significantly minimizes the risk of it inventing nonexistent columns or relationships. * **Query validation:** Every LLM-generated query is checked against the schema and executed through the database, guaranteeing factual output. * **Traceability:** Users can always view the generated SQL query, giving full transparency into how the result was produced. By grounding the model in enterprise data and maintaining full transparency, DataLinks gives organizations the power of natural language querying without the risk of misinformation or hallucinated results. ## From queries to business insights Once data can be queried naturally, insight becomes immediate. Executives and analysts no longer need to wait for data teams to prepare reports. Instead, they can explore information directly, following their questions where they lead. Some examples of the insights that can be unlocked include: * **Compliance and risk:** Identify indirect links between entities and sanctioned organizations. * **Procurement optimization:** Discover overlapping suppliers across business units to consolidate spend. * **Financial intelligence:** Correlate company performance metrics with supply chain dependencies. * **Operational monitoring:** Surface anomalies, trends, and relationships across regions or product lines. These insights come from structured connections between datasets, not isolated tables. The LLM simply makes navigating those connections fast and intuitive. ## Why this matters Enterprises spend millions each year trying to extract value from data, but the bottleneck often lies between *knowing what to ask* and *how to ask it*. DataLinks removes that barrier by allowing anyone, not just SQL experts, to query their data through plain language. Because the platform understands both the structure and the meaning of the data, it can generate high-quality queries that reflect real business logic. This combination of semantic structure and LLM interpretation turns querying into an intelligent conversation with your data. ## Example: Deep search across connected datasets You can use query language to traverse multiple degrees of connections in the knowledge map to uncover indirect relationships that matter for compliance and risk. For example, the following query starts from a specific company in the registry, explores its network, and then looks for any links to sanctions data: ``` Ontology("registry/companies") .filter("full_name" == "Qualcomm Technologies, Inc.") .searchAround(5) .find("sanctions/companies") ``` This query works in several steps: * `Ontology("registry/companies")` selects the companies registry dataset as the starting point. * `.filter("full_name" == "Qualcomm Technologies, Inc.")` narrows the focus to a single legal entity based on its full registered name. * `.searchAround(5)` walks the knowledge map up to five degrees of connections away from that company, following the defined links between datasets such as ownership, subsidiaries, and related entities. * `.find("sanctions/companies")` returns the companies in the sanctions dataset that are discovered within that five-degree reach. This kind of deep search can reveal whether a company has direct or indirect exposure to sanctioned entities, without requiring the user to know ahead of time how those relationships are structured. ## The foundation of data-driven decision making When querying works at this level, AI becomes more than a tool for analysis; it becomes a partner in reasoning. Clean, connected, and well-structured data combined with LLM-driven querying gives organizations the ability to move from static reports to continuous discovery. With DataLinks, insight is no longer locked behind technical barriers. It becomes a shared capability across the enterprise, available to every team and every question. # Introduction to DataLinks Source: https://docs.landfall.ai/get-started/intro-datalinks DataLinks is a platform that turns scattered data into structured knowledge that both humans and AI can actually use. Instead of forcing you to clean, reshape, merge, or premodel your data before you can start asking questions, DataLinks learns from your data as it is, builds structure where it is missing, and then gives you a simple way to explore and query it with clarity and confidence. This makes DataLinks a semantic knowledge platform. Your spreadsheets, CSVs, exports, PDFs, and structured systems become part of one unified knowledge network that humans can query over and AI can reason over without hallucinating or guessing. ## How DataLinks works DataLinks follows three stages that work together as one workflow. DataLinks Ontology Diagram **Ingest**\ The platform takes in your data from spreadsheets, databases, APIs, uploads, or files. During ingestion, DataLinks uses its cleanup and normalization layer to apply structure and meaning. Learn more about [Ingestion and Cleaning](/concepts/ingest-clean). **Interconnect**\ As soon as data is inside the platform, DataLinks automatically finds relationships between values across datasets. These relationships are stored as links. Together, these links form a knowledge map that reflects how your business entities relate in the real world. Learn more about [Interconnection (Knowledge Maps)](/concepts/interconnection). **Inquire**\ Once your data is clean and connected, you can ask questions using natural language or by writing queries. DataLinks uses a lightweight language model to generate accurate structured queries based on the shape and relationships inside your data. The important detail is that the model is not inventing answers. It is using your data as truth. Learn more about [Querying and Insights](/concepts/query-insights). ## What makes DataLinks different DataLinks does not ask you to solve structure before you get value. It builds it with you. Most BI (business intelligence) systems require months of schema design before you can start asking questions. Most AI systems simply cannot reason over enterprise-scale data. DataLinks solves both issues by building a semantic layer based on actual data rather than hand-built modeling. Key differences between DataLinks and traditional solutions include: * It does not require you to predefine a schema * It discovers relationships instead of asking you to hard-code them * It uses an LLM as a *reasoning layer,* not as a source of truth * It prevents hallucination by forcing all model reasoning to reference real data * It works with messy real-world data rather than idealized warehouse data ## Vision DataLinks is building a future in which knowledge is not locked inside specialized tools, departments or people. Data should not require SQL fluency or a data engineering team before you can ask a business question. The vision is a world where every employee is able to ask questions of the truth without worrying about where the truth lives. DataLinks exists to give organizations a semantic layer that makes enterprise data understandable by both humans and AI, so insight no longer depends on technical bottlenecks, modeling cycles, or dashboard backlogs. The goal is simple: turn organizational knowledge into something every person, and every AI agent, can use. ## Looking for platform access? DataLinks is currently available to select partners and early users. To request access or join the waitlist, [sign up for the waitlist](https://datalinks.com/newsletter). # DataLinks Web Platform QuickStart Guide Source: https://docs.landfall.ai/get-started/quickstart Learn how to ingest data, view connections, and query using the DataLinks web platform. ## Introduction This guide shows you how to use the DataLinks web platform to find shared sales opportunities across two North American data sources. You will learn by doing: uploading files, connecting records, and exploring the results directly in the platform. This guide focuses on the web platform only. If you'd like to learn about using the DataLinks API and SDK kit, you can try our [API/SDK QuickStart guide](/get-started/quickstart-api) instead. ## Scenario You're a sales manager for a dental products company in North America. Your goal is to see how your existing customer base overlaps with members of a major dental society to uncover new prospecting opportunities. You'll work with two datasets: * A JSON file that contains your current customers, including names, locations, and contact details * A dental society member list that includes dentists and clinic owners across the United States and Canada Using the DataLinks web platform, you'll ingest both datasets, manage how they connect, and query the linked data to find customers who are also society members or have professional ties to them. ## Outcome By the end of this guide, you will have a table showing which of your current customers also appear in the dental society list. You can explore these matches in the DataLinks platform or export them as a CSV file for follow-up. This exercise helps you practice the full workflow in DataLinks: importing data, linking records, exploring relationships, and using the insights for focused outreach. ## Prerequisites To follow along on your machine and complete the steps in this guide, make sure you have the following ready: 1. Access to a DataLinks account. Don't have an account? Contact [support@datalinks.com](support@datalinks.com) to request one. 2. Downloaded copies of the [example customer list](https://docs.cdn.datalinks.com/docs/quickstart-web/customer_list.json) and [example society list](https://docs.cdn.datalinks.com/docs/quickstart-web/society_list_web.txt). (Click to download.) With these things in place, you're ready to get started! ## Part 1: Create your namespace and first dataset