---
sidebar_position: 999
title: Creating a new integration
description: Guidelines for integrating your application with MotherDuck, including connection strings and custom user agent configuration.
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

Integrating with MotherDuck follows the same pattern as integrating with DuckDB, so you can use the same client APIs and frameworks.

There are three differences:

1. Use `md:` or `md:analytics` as the connection string instead of a local filesystem path.
2. Pass `motherduck_token` through a config dictionary, connection string parameter, or environment variable.
3. Pass `custom_user_agent` so MotherDuck can identify the integration in query history.

### Choose a `custom_user_agent` format {#custom-user-agent-format}

Use the format `integration/version(metadata1,metadata2)`. The version and metadata sections are optional.

- Avoid spaces in the integration and version sections.
- Separate multiple metadata values with commas.
- If you plan to group by one workload label later, put it first in the metadata list.

Examples:

- `catalogsync`
- `catalogsync/5.1.5.1`
- `catalogsync/5.1.5.1(batchload)`
- `catalogsync/5.1.5.1(batchload,useast1)`

## Language and framework examples {#custom-user-agent-examples}

<Tabs groupId="integration-language">
  <TabItem value="python" label="Python" default>

```python
con = duckdb.connect("md:analytics", config={
    "motherduck_token": token,
    "custom_user_agent": "catalogsync/5.1.5.1(batchload,useast1)"
})
```

  </TabItem>
  <TabItem value="sqlalchemy" label="SQLAlchemy">

```python
eng = create_engine("duckdb:///md:analytics", connect_args={
    "config": {
        "motherduck_token": token,
        "custom_user_agent": "catalogsync/5.1.5.1(batchload,useast1)"
    }
})
```

  </TabItem>
  <TabItem value="java" label="Java / JDBC">

```java
Properties config = new Properties();
config.setProperty("motherduck_token", token);
config.setProperty("custom_user_agent", "catalogsync/5.1.5.1(batchload,useast1)");
Connection mdConn = DriverManager.getConnection("jdbc:duckdb:md:analytics", config);
```

  </TabItem>
  <TabItem value="nodejs" label="Node.js">

```javascript
import { DuckDBInstance } from '@duckdb/node-api'

const instance = await DuckDBInstance.create("md:analytics", {
    motherduck_token: token,
    custom_user_agent: "catalogsync/5.1.5.1(batchload,useast1)"
})
const conn = await instance.connect()
```

  </TabItem>
  <TabItem value="go" label="Go">

```go
dsn := fmt.Sprintf(
    "md:analytics?motherduck_token=%s&custom_user_agent=%s",
    url.QueryEscape(token),
    url.QueryEscape("catalogsync/5.1.5.1(batchload,useast1)"),
)
db, err := sql.Open("duckdb", dsn)
```

  </TabItem>
</Tabs>

## Implementation best practices

If you use DuckDB or MotherDuck in a shared environment where one process serves multiple users, the connection string must be unique per user.

You can disambiguate the connection string with a user-specific parameter such as `md:analytics?session_user=<user_id>`.

If you pass `motherduck_token` in the connection string, ensure your application does not log it in plaintext.
