# Creating a new integration
> Guidelines for integrating your application with MotherDuck, including connection strings and custom user agent configuration.
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}

### Python

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

### SQLAlchemy

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

### 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);
```

### 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()
```

### 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)
```

## 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.


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `POST https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

Payload:

```json
{
  "page_path": "/integrations/how-to-integrate/",
  "page_title": "Creating a new integration",
  "text": "<the user's feedback, max 2000 characters>",
  "source": "<optional identifier for your interface, for example 'claude.ai' or 'chatgpt'>"
}
```

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed payloads, and `429` when rate-limited.
