pipedrive-go

module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 30, 2026 License: MIT

README

pipedrive-go

Go SDK for the Pipedrive API with a handwritten, stable public surface.

  • API v2: full support
  • API v1: legacy-only (endpoints not present in v2)

Generated OpenAPI clients are internal-only; use the pipedrive/v1 and pipedrive/v2 packages.

API versions

This SDK is v2-first. Use pipedrive/v2 for new work and only reach for pipedrive/v1 when an endpoint is not available in v2. The v1 surface is derived from the v1 OpenAPI spec with all v2-covered operations removed, so endpoints migrate out of v1 automatically as v2 grows.

Endpoint tables:

  • v2: docs/endpoints-v2.md
  • v1 legacy: docs/endpoints-v1-legacy.md

Install

go get github.com/juhokoskela/pipedrive-go@latest

Go 1.25+ is required.

To pin a specific version:

go get github.com/juhokoskela/pipedrive-go@v1.0.0

Quickstart (API token)

v2:

package main

import (
	"context"
	"log"

	"github.com/juhokoskela/pipedrive-go/pipedrive"
	v2 "github.com/juhokoskela/pipedrive-go/pipedrive/v2"
)

func main() {
	client, err := v2.NewClient(pipedrive.Config{
		Auth: pipedrive.APITokenAuth("YOUR_API_TOKEN"),
	})
	if err != nil {
		log.Fatal(err)
	}

	pipelines, _, err := client.Pipelines.List(
		context.Background(),
		v2.WithPipelinesPageSize(50),
	)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("pipelines=%d", len(pipelines))
}

v1 legacy:

client, err := v1.NewClient(pipedrive.Config{
	Auth: pipedrive.APITokenAuth("YOUR_API_TOKEN"),
})
if err != nil {
	log.Fatal(err)
}

currencies, err := client.Currencies.List(context.Background(), v1.ListCurrenciesRequest{})
if err != nil {
	log.Fatal(err)
}
log.Printf("currencies=%d", len(currencies))

Pagination

Cursor pagination helpers are exposed as ListPager and ForEach:

pager := client.Deals.ListPager(v2.WithDealsPageSize(100))
err := pager.ForEach(context.Background(), func(d v2.Deal) error {
	log.Printf("deal id=%d title=%s", d.ID, d.Title)
	return nil
})
if err != nil {
	log.Fatal(err)
}

OAuth2

Use the v1 OAuth helper to build the authorize URL and exchange tokens, then pass the access token into a v2 client.

import (
	"context"
	"encoding/base64"
	"log"

	"golang.org/x/oauth2"

	"github.com/juhokoskela/pipedrive-go/pipedrive"
	v1 "github.com/juhokoskela/pipedrive-go/pipedrive/v1"
	v2 "github.com/juhokoskela/pipedrive-go/pipedrive/v2"
)

ctx := context.Background()
oauthClient, _ := v1.NewClient(pipedrive.Config{})

authURL, err := oauthClient.OAuth.Authorize(
	ctx,
	v1.WithOAuthClientID(clientID),
	v1.WithOAuthRedirectURI(redirectURI),
	v1.WithOAuthState("state123"),
)
if err != nil {
	log.Fatal(err)
}
log.Printf("open: %s", authURL)

authHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientID+":"+clientSecret))
tokens, err := oauthClient.OAuth.GetTokens(
	ctx,
	v1.WithOAuthAuthorization(authHeader),
	v1.WithOAuthCode(code),
	v1.WithOAuthRedirectURI(redirectURI),
)
if err != nil {
	log.Fatal(err)
}

ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: tokens.AccessToken})
apiClient, _ := v2.NewClient(pipedrive.Config{
	BaseURL: tokens.APIDomain + "/api/v2",
	Auth:    pipedrive.OAuth2Auth{TokenSource: ts},
})

Retries and per-request options

Retries are enabled by default for 429/502/503/504 with backoff and jitter. Override globally with RetryPolicy, or per call with request options:

policy := pipedrive.DefaultRetryPolicy()
policy.MaxAttempts = 2

client, _ := v2.NewClient(pipedrive.Config{
	Auth:        pipedrive.APITokenAuth("YOUR_API_TOKEN"),
	RetryPolicy: &policy,
})

deal, err := client.Deals.Get(
	context.Background(),
	v2.DealID(123),
	v2.WithDealRequestOptions(pipedrive.WithNoRetry()),
)

Custom HTTP and middleware

client, _ := v2.NewClient(pipedrive.Config{
	Auth:       pipedrive.APITokenAuth("YOUR_API_TOKEN"),
	HTTPClient: customClient,
	Middleware: []pipedrive.Middleware{loggingMiddleware},
	UserAgent:  "my-app/1.0",
})

Raw API escape hatch

import "net/http"

var out struct {
	Data []v2.Pipeline `json:"data"`
}
err := client.Raw.Do(context.Background(), http.MethodGet, "/pipelines", nil, nil, &out)

Integration checks

Opt-in integration tests (skipped by default):

PIPEDRIVE_API_TOKEN=... go test ./pipedrive -run Integration -v
PIPEDRIVE_API_TOKEN=... PIPEDRIVE_INTEGRATION_WRITE=1 go test ./pipedrive -run IntegrationV2OrganizationCreateDelete -v

Smoke CLI:

PIPEDRIVE_API_TOKEN=... go run ./cmd/smoke

Optional env overrides:

  • PIPEDRIVE_BASE_URL_V1
  • PIPEDRIVE_BASE_URL_V2
  • PIPEDRIVE_SMOKE_TIMEOUT

Examples

See the runnable examples in examples/:

  • examples/token for API token usage
  • examples/oauth for OAuth2 usage

Versioning

The module follows semantic versioning and does not encode Pipedrive API versioning in the module path. The v1/v2 distinction is in the package path, not the module version. See RELEASING.md for release steps.

Development

make update-specs
make derive-v1-legacy
make generate
make docs
make fmt
make lint
go test ./...

Directories

Path Synopsis
cmd
endpoint-docs command
smoke command
examples
oauth command
token command
internal
gen/v1
Package v1 provides primitives to interact with the openapi HTTP API.
Package v1 provides primitives to interact with the openapi HTTP API.
gen/v2
Package v2 provides primitives to interact with the openapi HTTP API.
Package v2 provides primitives to interact with the openapi HTTP API.
v1
v2

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL