Guides
Contacts, segments & audiences
Store contacts with typed properties, group them in segments for broadcasts, and keep unsubscribes in sync with the suppression list. Legacy audiences are supported.
Contacts are the people you send broadcasts to:
- Contacts are global to your account and unique by email.
- Segments are named groups. A contact can belong to any number of segments.
- Audiences are the legacy name for segments, kept so older code keeps working.
Contacts
import { Pidgely } from 'pidgely';
const pidgely = new Pidgely(process.env.PIDGELY_API_KEY);
const { data, error } = await pidgely.contacts.create({
email: 'steve@example.com',
firstName: 'Steve',
lastName: 'Wozniak',
properties: {
plan: 'pro',
seats: 5,
beta: true,
},
segments: [
{
id: '0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48',
},
],
});
console.log(data ?? error);import os
import pidgely
pidgely.api_key = os.environ["PIDGELY_API_KEY"]
result = pidgely.Contacts.create({
"email": "steve@example.com",
"first_name": "Steve",
"last_name": "Wozniak",
"properties": {
"plan": "pro",
"seats": 5,
"beta": True,
},
"segments": [
{
"id": "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48",
},
],
})
print(result)<?php
require __DIR__ . '/vendor/autoload.php';
$pidgely = Pidgely::client(getenv('PIDGELY_API_KEY'));
$result = $pidgely->contacts->create([
'email' => 'steve@example.com',
'first_name' => 'Steve',
'last_name' => 'Wozniak',
'properties' => [
'plan' => 'pro',
'seats' => 5,
'beta' => true,
],
'segments' => [
[
'id' => '0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48',
],
],
]);
var_dump($result);package main
import (
"context"
"fmt"
"os"
"github.com/pidgely/pidgely-go"
)
func main() {
ctx := context.Background()
client := pidgely.NewClient(os.Getenv("PIDGELY_API_KEY"))
result, err := client.Contacts.Create(ctx, &pidgely.CreateContactRequest{
Email: "steve@example.com",
FirstName: "Steve",
LastName: "Wozniak",
Properties: map[string]any{
"plan": "pro",
"seats": 5,
"beta": true,
},
Segments: []pidgely.Segment{
{
Id: "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48",
},
},
})
if err != nil {
panic(err)
}
fmt.Println(result)
}require "pidgely"
Pidgely.api_key = ENV["PIDGELY_API_KEY"]
result = Pidgely::Contacts.create({
email: "steve@example.com",
first_name: "Steve",
last_name: "Wozniak",
properties: {
plan: "pro",
seats: 5,
beta: true
},
segments: [
{
id: "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48"
}
]
})
puts resultcurl -X POST 'https://api.pidgely.com/contacts' \
-H "Authorization: Bearer $PIDGELY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"email": "steve@example.com",
"first_name": "Steve",
"last_name": "Wozniak",
"properties": {
"plan": "pro",
"seats": 5,
"beta": true
},
"segments": [
{
"id": "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48"
}
]
}'POST /contactsis an upsert: posting an email that already exists updates that contact.first_nameandlast_nameare up to 200 characters.- Properties: up to 100 per contact. Keys match
^[A-Za-z_][A-Za-z0-9_]{0,49}$; values are strings (up to 2,000 characters), numbers or booleans. Set a key tonullto delete it. Reads return each property as{ "value": …, "type": "string" | "number" | "boolean" }. - Retrieve, update and delete by id or email:
GET /contacts/steve@example.comworks. topicsis not supported yet and is rejected.
Unsubscribes and the suppression list
unsubscribed and the suppression list stay in sync, both ways:
| Change | Effect |
|---|---|
| The contact clicks the unsubscribe link of a broadcast | An unsubscribe suppression is added and the contact becomes unsubscribed: true |
You set unsubscribed: true |
An unsubscribe suppression is added |
You set unsubscribed: false |
The unsubscribe suppression is removed (bounce and complaint suppressions are never removed this way) |
You remove an unsubscribe suppression |
The contact becomes subscribed again |
You create a contact whose address already has an unsubscribe suppression |
The contact starts as unsubscribed |
Suppressions are account-wide: an address that unsubscribed from broadcasts is also skipped by transactional sends. Deleting a contact keeps its suppression.
Segments
Create a segment, then add contacts to it:
import { Pidgely } from 'pidgely';
const pidgely = new Pidgely(process.env.PIDGELY_API_KEY);
const { data, error } = await pidgely.segments.create({
name: 'Newsletter',
});
console.log(data ?? error);import os
import pidgely
pidgely.api_key = os.environ["PIDGELY_API_KEY"]
result = pidgely.Segments.create({
"name": "Newsletter",
})
print(result)<?php
require __DIR__ . '/vendor/autoload.php';
$pidgely = Pidgely::client(getenv('PIDGELY_API_KEY'));
$result = $pidgely->segments->create([
'name' => 'Newsletter',
]);
var_dump($result);package main
import (
"context"
"fmt"
"os"
"github.com/pidgely/pidgely-go"
)
func main() {
ctx := context.Background()
client := pidgely.NewClient(os.Getenv("PIDGELY_API_KEY"))
result, err := client.Segments.Create(ctx, &pidgely.CreateSegmentRequest{
Name: "Newsletter",
})
if err != nil {
panic(err)
}
fmt.Println(result)
}require "pidgely"
Pidgely.api_key = ENV["PIDGELY_API_KEY"]
result = Pidgely::Segments.create({
name: "Newsletter"
})
puts resultcurl -X POST 'https://api.pidgely.com/segments' \
-H "Authorization: Bearer $PIDGELY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Newsletter"
}'import { Pidgely } from 'pidgely';
const pidgely = new Pidgely(process.env.PIDGELY_API_KEY);
const { data, error } = await pidgely.contacts.segments.add({
email: 'steve@example.com',
segmentId: '0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48',
});
console.log(data ?? error);import os
import pidgely
pidgely.api_key = os.environ["PIDGELY_API_KEY"]
result = pidgely.Contacts.Segments.add({
"email": "steve@example.com",
"segment_id": "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48",
})
print(result)<?php
require __DIR__ . '/vendor/autoload.php';
$pidgely = Pidgely::client(getenv('PIDGELY_API_KEY'));
$result = $pidgely->contacts->segments->add([
'email' => 'steve@example.com',
'segment_id' => '0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48',
]);
var_dump($result);package main
import (
"context"
"fmt"
"os"
"github.com/pidgely/pidgely-go"
)
func main() {
ctx := context.Background()
client := pidgely.NewClient(os.Getenv("PIDGELY_API_KEY"))
result, err := client.Contacts.Segments.Add(ctx, "steve@example.com", "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48")
if err != nil {
panic(err)
}
fmt.Println(result)
}require "pidgely"
Pidgely.api_key = ENV["PIDGELY_API_KEY"]
result = Pidgely::Contacts::Segments.add({
email: "steve@example.com",
segment_id: "0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48"
})
puts resultcurl -X POST 'https://api.pidgely.com/contacts/steve@example.com/segments/0199d7f5-9a3e-7d4b-a1c2-7e5f0b3d6c48' \
-H "Authorization: Bearer $PIDGELY_API_KEY"- List a segment's members with
GET /segments/{id}/contactsorGET /contacts?segment_id=…. - Removing a contact from a segment keeps the contact. Deleting a segment keeps its contacts.
- Segment names are 1–200 characters.
Audiences (legacy)
The /audiences endpoints are aliases of segments over the same global contacts, and broadcasts accept audience_id as an alias of segment_id.
Webhooks
Contact changes emit contact.created, contact.updated and contact.deleted webhooks with the contact's id, email, names, unsubscribed and timestamps.