# SDKs

> Official Pidgely SDKs for Go (published), Node.js, Python, PHP and Ruby (preview) - install, configure and send your first email.

Source: https://docs.pidgely.com/sdks/

| Language | Install | Repository | Status |
|---|---|---|---|
| Go | `go get github.com/pidgely/pidgely-go` | [pidgely/pidgely-go](https://github.com/pidgely/pidgely-go) | **v0.1 — published** |
| Node.js / TypeScript | `npm install pidgely` | [pidgely/pidgely-node](https://github.com/pidgely/pidgely-node) | Preview (0.1) — publishing soon |
| Python | `pip install pidgely` | [pidgely/pidgely-python](https://github.com/pidgely/pidgely-python) | Preview (0.1) — publishing soon |
| PHP | `composer require pidgely/pidgely-php guzzlehttp/guzzle` | [pidgely/pidgely-php](https://github.com/pidgely/pidgely-php) | Preview (0.1) — publishing soon |
| Ruby | `gem install pidgely` | [pidgely/pidgely-ruby](https://github.com/pidgely/pidgely-ruby) | Preview (0.1) — publishing soon |

> [!PREVIEW]
> The Go SDK is published (v0.1.0). The Node.js, Python, PHP and Ruby SDKs are open source and tested, and are being published to their registries now; until then, install them from their repositories. The [cURL](#plain-http) examples always work.

All SDKs share the same resources and method names (`emails.send`, `emails.get`, `batch.send`, `domains.create`, `domains.verify`, `apiKeys.create`, `contacts.*`, `segments.*`, `broadcasts.*`, `templates.*`, `webhooks.*`, `suppressions.*`), adapted to each language's conventions. Every page of the [API reference](https://docs.pidgely.com/api-reference/) shows the call in each language.

## Node.js

```bash
npm install pidgely
```

```js
import { Pidgely } from 'pidgely';

const pidgely = new Pidgely(process.env.PIDGELY_API_KEY); // or set PIDGELY_API_KEY and call new Pidgely()

const { data, error } = await pidgely.emails.send({
  from: 'Acme <onboarding@acme.com>',
  to: ['delivered@example.com'],
  subject: 'Hello from Pidgely',
  html: '<p>It works!</p>',
});

if (error) console.error(error); // { statusCode, name, message }
else console.log(data.id);
```

- **Zero dependencies**, uses the global `fetch`: Node.js 18+, Bun, Deno, Cloudflare Workers, Vercel Edge.
- **Never throws** on API or network errors: methods resolve to `{ data, error, headers }`.
- **Idempotency and retries**: send methods accept `{ idempotencyKey }`; requests are retried with backoff (honouring `Retry-After`) up to `maxRetries` (default 2). A `POST` without an idempotency key is never retried after a 5xx or network error.
- **Inputs in camelCase** (`replyTo`, `scheduledAt`, `segmentId`), responses exactly as the API returns them.
- **React Email**: pass `react` instead of `html` (renders with `@react-email/render`).
- **Webhook verification**: `await verifyWebhook({ payload, headers, webhookSecret })` (see [Webhooks](https://docs.pidgely.com/guides/webhooks/#verify-signatures)).

```js
const pidgely = new Pidgely(process.env.PIDGELY_API_KEY, {
  baseUrl: 'https://api.pidgely.com', // or PIDGELY_BASE_URL
  timeout: 30_000, // per attempt, ms
  maxRetries: 2,
});
```

## Python

```bash
pip install pidgely
```

```python
import os
import pidgely

pidgely.api_key = os.environ["PIDGELY_API_KEY"]

email = pidgely.Emails.send({
    "from": "Acme <onboarding@acme.com>",
    "to": ["delivered@example.com"],
    "subject": "Hello from Pidgely",
    "html": "<p>It works!</p>",
})
```

## PHP

```bash
# Guzzle is the suggested HTTP client; any PSR-18 client works
composer require pidgely/pidgely-php guzzlehttp/guzzle
```

```php
<?php
require __DIR__ . '/vendor/autoload.php';

$pidgely = Pidgely::client(getenv('PIDGELY_API_KEY'));

$email = $pidgely->emails->send([
    'from' => 'Acme <onboarding@acme.com>',
    'to' => ['delivered@example.com'],
    'subject' => 'Hello from Pidgely',
    'html' => '<p>It works!</p>',
]);
```

## Go

```bash
go get github.com/pidgely/pidgely-go
```

```go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/pidgely/pidgely-go"
)

func main() {
	ctx := context.Background()
	client := pidgely.NewClient(os.Getenv("PIDGELY_API_KEY"))

	sent, err := client.Emails.Send(ctx, &pidgely.SendEmailRequest{
		From:    "Acme <onboarding@acme.com>",
		To:      []string{"delivered@example.com"},
		Subject: "Hello from Pidgely",
		Html:    "<p>It works!</p>",
	}, pidgely.WithIdempotencyKey("hello-1"))
	if err != nil {
		panic(err) // *pidgely.Error carries StatusCode and Name
	}
	fmt.Println(sent.Id)
}
```

Request options such as `pidgely.WithIdempotencyKey(…)` and `pidgely.WithBatchValidation(pidgely.BatchPermissive)` go after the request; list methods take `*pidgely.ListParams` (or `nil`).

## Ruby

```bash
gem install pidgely
```

```ruby
require "pidgely"

Pidgely.api_key = ENV["PIDGELY_API_KEY"]

email = Pidgely::Emails.send({
  from: "Acme <onboarding@acme.com>",
  to: ["delivered@example.com"],
  subject: "Hello from Pidgely",
  html: "<p>It works!</p>"
})
```

## Plain HTTP

Every API reference page also has the raw request as cURL. The [OpenAPI document](https://docs.pidgely.com/openapi.yaml) ([JSON](https://docs.pidgely.com/openapi.json)) describes the whole API and can generate a client for any other language.

## Coming from another provider?

Moving existing code from Resend? See [Migrate from Resend](https://docs.pidgely.com/guides/migrate-from-resend/).
