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

# Query Database

> Query your workspace Database securely through the Deepline API or SDK, without exposing a PostgreSQL connection string.

[Human guide: work with your agent →](https://deepline.com/docs/human/database-access.md)

> [!NOTE]
>
> Read one bounded customer query and distinguish permitted customer writes from
> managed data.

For an application or agent, query the Database through the Deepline API. Your
Deepline API key selects the workspace. The API runs one bounded SQL statement
against that workspace's Database. You do not need to expose a PostgreSQL
connection string.

Use a direct PostgreSQL URI only when a database-native tool, such as BI or
`psql`, genuinely needs one.

## Query the API securely

Send the request from your server, worker, or trusted agent runtime. Keep
`DEEPLINE_API_KEY` in server-side secret storage. Never put it in a browser
application or commit it to source control.

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
curl -sS -X POST https://code.deepline.com/api/v2/db/query \
  -H "Authorization: Bearer $DEEPLINE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT domain, company_name FROM enrichments.companies ORDER BY updated_at DESC LIMIT 20",
    "max_rows": 20
  }'
```

> [!TIP]
>
> A successful response returns `rows`, `columns`, `row_count_returned`, and
> `truncated`. An empty `rows` array means the query ran but found no matches.

The API accepts one SQL statement and up to 1,000 returned rows per request.
Use `max_rows` to bound the result you need.

## Use the SDK

The SDK uses the same API boundary:

```ts theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
import { DeeplineClient } from 'deepline';

const client = new DeeplineClient({
  apiKey: process.env.DEEPLINE_API_KEY,
});

const result = await client.db.query({
  sql: 'SELECT domain, company_name FROM enrichments.companies ORDER BY updated_at DESC LIMIT 20',
  maxRows: 20,
});
```

## Query rules

| Operation | Where it is allowed |
| - | - |
| Read a managed Database view | `SELECT`, `EXPLAIN`, read-only `WITH`, and aggregates |
| Create or change agent-owned data | Qualified `storage.<table>` or an allowed customer-managed schema |
| Change Deepline-managed data | Never through this API |

For example, an agent or application can create its own scratch table:

```sql theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
CREATE TABLE IF NOT EXISTS storage.agent_notes (
  id text PRIMARY KEY,
  note text NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now()
);
```

These statements are intentionally blocked:

```sql theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
CREATE TABLE agent_notes (...);
DELETE FROM enrichments.companies WHERE domain = 'example.com';
```

Customer-managed schemas can also be created and used through this API, for
example `CREATE SCHEMA tenant_custom`, followed by a separate qualified
`CREATE TABLE tenant_custom.agent_notes (...)` statement. Reserved names and
internal objects remain protected. See the [Database contract](https://deepline.com/docs/features/postgresql-database.md).

## Keep the boundary safe

* Do not forward arbitrary browser input as SQL. Build queries in trusted
  server-side code and constrain the tables, columns, and filters your product
  permits.
* Do not accept query text from an end user. Use fixed, allowlisted queries and
  validate request values before your server builds the SQL. Treat raw SQL as
  privileged input.
* Set `max_rows` and select only the columns your caller needs.
* Use the Database for working state. Write approved outcomes to your CRM. See
  [Where data lives](https://deepline.com/docs/data-lifecycle.md).

## Direct PostgreSQL access

Use a Database URI only for a database-native application or BI tool. Obtain
it from the dashboard's Database Access flow, store it in server-side secret
storage, and write only to permitted customer storage objects. Provisioning, URI reveal, and password
rotation are dashboard/admin-session controls. they are not the public query
API.

> **[SDK API reference](https://deepline.com/docs/sdk-v2/api-reference.md)**
>
> See the supported `POST /api/v2/db/query` contract and SDK method.

## Verify this task

Inspect returned columns, row count, and truncation. Test writes only in permitted customer-owned objects, not managed enrichment views.

Ask your agent to explain a failed check before repeating work or expanding the scope.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.