Programs
Affiliate programs — data model, status lifecycle, REST API, PHP data access, engagement types, and transaction compilers.
Last updated: April 9, 2026
Programs
A program defines a set of rules for how collaborators earn rewards. Each program specifies an incentive structure (how rewards are calculated), engagement types (what actions trigger attribution), and a currency unit (what the rewards are denominated in). Programs are the central organizing concept in Siren. Collaborators are enrolled in programs, and conversions, obligations, and fulfillments all trace back to the program that governs them.
The program object
| Field | REST name | PHP getter | Type | Description |
|---|---|---|---|---|
| ID | id | getId() | integer | Unique identifier |
| Name | name | getName() | string | Display name of the program |
| Description | description | getDescription() | string | Human-readable description of what the program does |
| Incentive type | incentiveType | getIncentiveType() | string | Incentive type identifier (e.g., commission) |
| Incentive resolver | incentiveResolverType | getIncentiveResolverType() | string | Strategy used to resolve incentive amounts |
| Status | status | getStatus() | string | Current status: active, inactive, draft, or deleted |
| Units | units | getUnits() | string | Currency or unit identifier for reward denominations (e.g., USD, points) |
| Created | dateCreated | getCreatedDate() | datetime | When the record was created |
| Modified | dateModified | getModifiedDate() | datetime | When the record was last updated |
Extended fields (REST only, via ?fields=)
These fields are resolved dynamically by the REST API field resolver system and must be explicitly requested:
| Field | Type | Description |
|---|---|---|
collaborators | array | List of collaborators enrolled in this program, each with id and nickname |
collaboratorCount | integer | Total number of collaborators enrolled in this program |
engagementsCount | integer | Total number of engagements associated with this program |
engagementTypes | array | Engagement type configurations for this program, each with id, type, and value |
transactionCompilers | array | Active transaction compilers for this program, each with id and compiler |
incentiveConfig | object | Combined incentive type and resolver metadata, each with id and name |
incentiveCalculation | object | Incentive calculation settings including transactionPercent, payoutPerTransaction, payoutPerProduct, payoutPerLead, activeConversionTypes, autoApprove, and leadRequalificationDays |
expirationDays | integer or null | Number of days before the program’s conversions expire, or null if no expiration is set |
lineItemFilters | object or null | Transaction line item filtering rules including withTypes, collaboratorOwned, withSkus, and inCategories |
When extended fields are requested, incentiveType and incentiveResolverType are enriched from plain string identifiers to objects containing both id and name.
Status lifecycle
| Status | Description |
|---|---|
active | Program is live and accepting new engagements and conversions. |
inactive | Program is paused. Existing data is preserved, but new activity is not processed. |
deleted | Soft-deleted. A second DELETE call permanently removes the record. Bulk restore moves the program back to inactive. |
Accessing program data
# List active programs
curl -X GET "https://your-site.com/wp-json/siren/v1/programs?status=active" \
-H "Authorization: Bearer YOUR_TOKEN"
# Get a single program with extended fields
curl -X GET "https://your-site.com/wp-json/siren/v1/programs/5?fields=id,name,status,collaboratorCount,engagementTypes,incentiveCalculation" \
-H "Authorization: Bearer YOUR_TOKEN" use Siren\Programs\Core\Datastores\Program\Interfaces\ProgramDatastore;
class MyService
{
protected ProgramDatastore $programs;
public function __construct(ProgramDatastore $programs)
{
$this->programs = $programs;
}
public function getActivePrograms(): array
{
return $this->programs->andWhere([
['column' => 'status', 'operator' => '=', 'value' => 'active']
]);
}
} use Siren\Programs\Core\Facades\Programs;
$activePrograms = Programs::andWhere([
['column' => 'status', 'operator' => '=', 'value' => 'active']
]);
$program = Programs::getById(42); Siren is built on an event-driven architecture. If you find yourself creating programs manually in code, consider whether your use case is better served by the admin UI or the recipe import system. Direct datastore writes bypass the normal event flow and can leave related records out of sync.
PHP domain methods
Looking up a collaborator’s programs
getCollaboratorPrograms retrieves all programs a specific collaborator participates in. This queries the junction table that links collaborators to programs and returns the full program models.
use Siren\Programs\Core\Datastores\Program\Interfaces\ProgramDatastore;
class CollaboratorDashboard
{
protected ProgramDatastore $programs;
public function __construct(ProgramDatastore $programs)
{
$this->programs = $programs;
}
public function listPrograms(int $collaboratorId): array
{
// Returns Program[] - defaults to 10 results starting at offset 0
return $this->programs->getCollaboratorPrograms($collaboratorId);
}
public function listAllPrograms(int $collaboratorId): array
{
// Paginate with custom limit and offset
return $this->programs->getCollaboratorPrograms($collaboratorId, 50, 0);
}
} use Siren\Programs\Core\Facades\Programs;
// Get first 10 programs for a collaborator
$programs = Programs::getCollaboratorPrograms($collaboratorId);
// With pagination
$programs = Programs::getCollaboratorPrograms($collaboratorId, 25, 0); Counting collaborators in a program
getCollaboratorCount returns the estimated number of collaborators enrolled in a given program.
$count = $this->programs->getCollaboratorCount($programId); use Siren\Programs\Core\Facades\Programs;
$count = Programs::getCollaboratorCount($programId); Engagement types
Each program can be configured with one or more engagement types that define which kinds of engagements are tracked and how they are valued. Engagement types are stored as separate records linked to a program by programId.
The engagement type model (Siren\Programs\Core\Models\ProgramEngagementType) has the following fields:
| Field | PHP getter | Type | Description |
|---|---|---|---|
| ID | getId() | integer | Primary key |
| Program | getProgramId() | integer | The program this engagement type belongs to |
| Engagement type | getEngagementType() | string | Type identifier (e.g., saleTransaction, leadCapture) |
| Engagement value | getEngagementValue() | float | Numeric value or weight assigned to this engagement type |
Accessing engagement type data
use Siren\Programs\Core\Datastores\ProgramEngagementTypes\Interfaces\ProgramEngagementTypeDatastore;
class IncentiveCalculator
{
protected ProgramEngagementTypeDatastore $engagementTypes;
public function __construct(ProgramEngagementTypeDatastore $engagementTypes)
{
$this->engagementTypes = $engagementTypes;
}
public function getAllEngagementTypes(int $programId): array
{
return $this->engagementTypes->getProgramEngagementTypes($programId);
}
public function getSaleValue(int $programId): float
{
$type = $this->engagementTypes->getEngagementTypeForProgram(
$programId,
'saleTransaction'
);
return $type->getEngagementValue();
}
} use Siren\Programs\Core\Facades\ProgramEngagementTypes;
// Get all engagement types for a program
$types = ProgramEngagementTypes::getProgramEngagementTypes($programId);
// Get a specific engagement type configuration
// Throws RecordNotFoundException if the program doesn't have this type configured
$saleType = ProgramEngagementTypes::getEngagementTypeForProgram(
$programId,
'saleTransaction'
);
$value = $saleType->getEngagementValue(); getProgramEngagementTypes returns all engagement types configured for a program. getEngagementTypeForProgram retrieves a single engagement type by program ID and type identifier, and throws RecordNotFoundException if the combination doesn’t exist.
Transaction compilers
Transaction compilers define how a program calculates transaction amounts. Each program can have one or more compilers registered, and each compiler record links a program to a compiler strategy identifier. For a user-level overview of the built-in filters (line items, discounts, fees, shipping, taxes) and how they’re configured through the admin UI, see Line Item Filters.
The transaction compiler model (Siren\Programs\Core\Models\ProgramTransactionCompiler) has the following fields:
| Field | PHP getter | Type | Description |
|---|---|---|---|
| ID | getId() | integer | Primary key |
| Program | getProgramId() | integer | The program this compiler belongs to |
| Compiler | getTransactionCompiler() | string | The compiler strategy identifier |
Accessing transaction compiler data
use Siren\Programs\Core\Datastores\ProgramTransactionCompilers\Interfaces\ProgramTransactionCompilerDatastore;
class CompilerInspector
{
protected ProgramTransactionCompilerDatastore $compilers;
public function __construct(ProgramTransactionCompilerDatastore $compilers)
{
$this->compilers = $compilers;
}
public function getCompilers(int $programId): array
{
return $this->compilers->getProgramTransactionCompilers($programId);
}
} use Siren\Programs\Core\Facades\ProgramTransactionCompilers;
$compilers = ProgramTransactionCompilers::getProgramTransactionCompilers($programId);
foreach ($compilers as $compiler) {
echo $compiler->getTransactionCompiler();
} getProgramTransactionCompilers returns all transaction compiler records for a given program.
Relationships
- Collaborators (enrollment). Collaborators are enrolled in programs. The
collaboratorsandcollaboratorCountextended fields surface this relationship. A collaborator may belong to multiple programs. - Engagement Types (configuration). Each program defines which engagement types are valid for attribution. These are stored in a junction table and surfaced via the
engagementTypesextended field. - Transaction Compilers (configuration). Programs declare which transaction compilers apply when calculating conversion value. Surfaced via the
transactionCompilersextended field. - Program Groups (organization). Programs can be organized into groups via a junction table. The list endpoint supports filtering by
programGroupId. - Conversions (downstream). When an engagement attributed to a program results in a tracked outcome, a conversion is created referencing the program.
- Obligations (downstream). Approved conversions produce obligations governed by the program’s incentive configuration.
REST endpoints
See the individual endpoint pages in the sidebar for full request and response details, or browse the all REST endpoints reference.