| name | databricks-isv-telemetry-attribution |
| description | PWAF User-Agent telemetry: format, per-driver configuration (Python SDK, Java SDK/JDBC, Go SDK/SQL, Node.js, REST, Databricks Connect). Use when setting up User-Agent attribution in any connector. |
Telemetry & Attribution (PWAF)
User-Agent configuration for PWAF-compliant partner integrations across all Databricks drivers and SDKs. Reference: PWAF Telemetry & Attribution.
Why Telemetry is Required
PWAF requires User-Agent tagging in all partner integrations for:
| Purpose | Description |
|---|
| Usage Attribution | Track partner product usage for reporting |
| Joint Customer Visibility | Identify how many joint customers use the integration |
| GTM Initiatives | Measure integration adoption and effectiveness |
User-Agent Format
Required format:
<isv-name>_<product-name>/<product-version>
Rules:
- Use underscore (
_) as separator between ISV name and product name
- Use forward slash (
/) before version
- Keep ISV name consistent across all products
- Version is optional but recommended
Examples:
AcmePartner_DataConnector/2.1.0
BigCorp_ETLTool/3.5
MyCompany_AnalyticsPlatform/1.0.0-beta
SDK-level User-Agent Registration (withPartner / withProduct)
Per PWAF SDKs telemetry, Databricks SDKs use dedicated static/global registration functions. These register product and partner identifiers that are applied to all subsequent SDK HTTP requests. Call once before creating any client.
Java SDK
import com.databricks.sdk.core.UserAgent;
UserAgent.withProduct("<product-name>", "<product-version>");
UserAgent.withPartner("<isv-name>");
WorkspaceClient client = new WorkspaceClient(config);
Python SDK
from databricks.sdk import WorkspaceClient, useragent
useragent.with_partner("<isv-name>")
useragent.with_product("<product-name>", "<product-version>")
client = WorkspaceClient(host="https://<host>", token="<token>")
Go SDK
import (
"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/useragent"
)
useragent.WithPartner("<isv-name>")
useragent.WithProduct("<product-name>", "<product-version>")
client, err := databricks.NewWorkspaceClient(&databricks.Config{...})
Summary table
| SDK | Partner function | Product function | Scope |
|---|
| Java | UserAgent.withPartner(isv) | UserAgent.withProduct(name, ver) | Static/global |
| Python | useragent.with_partner(isv) | useragent.with_product(name, ver) | Module/global |
| Go | useragent.WithPartner(isv) | useragent.WithProduct(name, ver) | Package/global |
Note: These SDK functions are distinct from the driver-level UserAgentEntry property used by JDBC, ODBC, Node.js SQL driver, and Databricks SQL Driver for Go. Both approaches use the same <isv>_<product>/<version> format; the SDK functions decompose it into separate partner and product registrations.
JDBC Driver (OSS)
Per PWAF SQL Drivers telemetry, set UserAgentEntry on every JDBC connection.
Using JDBC URL
String jdbcUrl =
"jdbc:databricks://<host>:443;" +
"httpPath=<http-path>;" +
"AuthMech=11;" +
"Auth_Flow=1;" +
"OAuth2ClientId=<client-id>;" +
"OAuth2Secret=<client-secret>;" +
"SSL=1;" +
"UserAgentEntry=YourCompany_YourProduct/1.0.0";
Connection conn = DriverManager.getConnection(jdbcUrl);
Using Properties
Properties props = new Properties();
props.put("httpPath", "<http-path>");
props.put("AuthMech", "11");
props.put("Auth_Flow", "1");
props.put("OAuth2ClientId", "<client-id>");
props.put("OAuth2Secret", "<client-secret>");
props.put("SSL", "1");
props.put("UserAgentEntry", "YourCompany_YourProduct/1.0.0");
Connection conn = DriverManager.getConnection("jdbc:databricks://<host>:443", props);
Using DataSource
import com.databricks.client.jdbc.DataSource;
DataSource ds = new DataSource();
Properties props = new Properties();
props.setProperty("UserAgentEntry", "YourCompany_YourProduct/1.0.0");
props.setProperty("AuthMech", "11");
props.setProperty("Auth_Flow", "1");
props.setProperty("OAuth2ClientId", "<client-id>");
props.setProperty("OAuth2Secret", "<client-secret>");
props.setProperty("SSL", "1");
ds.setServerHostname("<host>");
ds.setPort(443);
ds.setHttpPath("<http-path>");
ds.setProperties(props);
Connection conn = ds.getConnection();
ODBC Driver
DSN Configuration (Linux/Mac)
In ~/.odbc.ini or /etc/odbc.ini:
[DatabricksConnection]
Driver=/opt/simba/spark/lib/64/libsparkodbc_sb64.so
Host=<server-hostname>
Port=443
HTTPPath=<http-path>
SSL=1
ThriftTransport=2
AuthMech=11
Auth_Flow=1
OAuth2ClientId=<client-id>
OAuth2Secret=<client-secret>
UserAgentEntry=YourCompany_YourProduct/1.0.0
DSN-less Connection String
Driver=/opt/simba/spark/lib/64/libsparkodbc_sb64.so;
Host=<server-hostname>;
Port=443;
HTTPPath=<http-path>;
SSL=1;
ThriftTransport=2;
AuthMech=11;
Auth_Flow=1;
OAuth2ClientId=<client-id>;
OAuth2Secret=<client-secret>;
UserAgentEntry=YourCompany_YourProduct/1.0.0;
Node.js Driver
const { DBSQLClient } = require('@databricks/sql');
const client = new DBSQLClient();
await client.connect({
host: process.env.DATABRICKS_HOST,
path: process.env.DATABRICKS_HTTP_PATH,
token: process.env.DATABRICKS_TOKEN,
userAgentEntry: 'YourCompany_YourProduct/1.0.0'
});
const session = await client.openSession();
const result = await session.executeStatement('SELECT 1');
Go Driver
package main
import (
"database/sql"
"os"
dbsql "github.com/databricks/databricks-sql-go"
)
func main() {
connector, err := dbsql.NewConnector(
dbsql.WithServerHostname(os.Getenv("DATABRICKS_HOST")),
dbsql.WithPort(443),
dbsql.WithHTTPPath(os.Getenv("DATABRICKS_HTTP_PATH")),
dbsql.WithAccessToken(os.Getenv("DATABRICKS_TOKEN")),
dbsql.WithUserAgentEntry("YourCompany_YourProduct/1.0.0"),
)
if err != nil {
panic(err)
}
db := sql.OpenDB(connector)
defer db.Close()
}
Python SQL Connector
from databricks import sql
connection = sql.connect(
server_hostname="<host>",
http_path="<http-path>",
access_token="<token>",
_user_agent_entry="YourCompany_YourProduct/1.0.0"
)
cursor = connection.cursor()
cursor.execute("SELECT 1")
print(cursor.fetchall())
cursor.close()
connection.close()
Python SQLAlchemy
Use user_agent_entry in connect_args (not _user_agent_entry; the latter is deprecated):
from sqlalchemy import create_engine, text
url = "databricks://token:<token>@<host>?http_path=<path>&catalog=main&schema=default"
engine = create_engine(url, connect_args={"user_agent_entry": "YourCompany_YourProduct/1.0.0"})
with engine.connect() as conn:
conn.execute(text("SELECT 1"))
Python SDK
Use the useragent module functions (recommended) for partner and product registration:
from databricks.sdk import WorkspaceClient, useragent
useragent.with_partner("YourCompany")
useragent.with_product("YourCompany_YourProduct", "1.0.0")
client = WorkspaceClient(
host="https://<host>",
token="<token>",
)
Note: The older product= / product_version= on WorkspaceClient or Config also works but useragent.with_partner() / useragent.with_product() is the recommended approach for partner integrations.
REST API (Direct HTTP)
When calling Databricks REST APIs directly, include the User-Agent header:
curl -X GET "https://<host>/api/2.0/clusters/list" \
-H "Authorization: Bearer <token>" \
-H "User-Agent: YourCompany_YourProduct/1.0.0"
Java (HttpClient)
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://<host>/api/2.0/clusters/list"))
.header("Authorization", "Bearer " + token)
.header("User-Agent", "YourCompany_YourProduct/1.0.0")
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
Databricks Connect
Use .userAgent() on the DatabricksSession.builder to set the partner User-Agent identifier. This is the PWAF-recommended approach.
Python
from databricks.connect import DatabricksSession
from databricks.sdk.core import Config
config = Config()
spark = (
DatabricksSession.builder
.sdkConfig(config)
.userAgent("YourCompany_YourProduct/1.0.0")
.getOrCreate()
)
Scala
import com.databricks.connect.DatabricksSession
val spark = DatabricksSession.builder
.userAgent("YourCompany_YourProduct/1.0.0")
.getOrCreate()
Note: The older product= / product_version= on Config also works internally, but .userAgent() on the session builder is the official PWAF pattern.
Validating Your Implementation
Method 1: Query History UI
- Go to Databricks workspace → SQL → Query History
- Look for the Source column
- Your User-Agent should appear there
Method 2: System Tables Query
SELECT
event_time,
user_agent,
action_name,
request_params
FROM system.access.audit
WHERE event_time > current_timestamp() - INTERVAL 2 DAYS
AND lower(user_agent) LIKE '%yourcompany%'
ORDER BY event_time DESC
LIMIT 100;
Note: Request access to system tables if needed.
Common Mistakes
| Mistake | Consequence | Fix |
|---|
| Using space instead of underscore | Inconsistent attribution | Use Company_Product not Company Product |
| Customer configures User-Agent | Unreliable tracking | Set it programmatically in your code |
| Missing User-Agent entirely | No partner attribution | Always include UserAgentEntry |
| Hardcoding wrong format | Parsing issues | Follow <isv>_<product>/<version> format |
| Different UA across products | Split attribution | Use consistent ISV name |