Notes
Activity-feed entries written by lifecycle events — data model, source linking, blueprint keys, REST API, and PHP data access.
Notes
A note is a single entry in Siren’s activity feed. Lifecycle events across the system (a conversion being approved, an obligation being issued, a payout being marked paid, and so on) each write a note and link it to every related record. Reading the notes for a record gives you a chronological history of everything Siren has done to that record. In the admin UI the collection of notes for a given record is surfaced as the activity feed.
Notes are written by the system. The REST and PHP APIs expose them for reading, rendering, and searching; there is no public endpoint for creating or editing notes by hand. If you need a note to exist, fire the event that the blueprint listens for.
The note object
| Field | REST name | PHP getter | Type | Description |
|---|---|---|---|---|
| ID | id | getId() | integer | Unique identifier |
| Content | content | getContent() | string | The blueprint key (for example, obligation_issued). The displayable text is resolved from this key at read time. |
| Creation source | creationSource | getCreationSource() | string | The entity type that caused the note to be written (for example, conversion). |
| Creation source ID | creationSourceId | getCreationSourceId() | integer | The ID of the entity that caused the note to be written. |
| Created | dateCreated | getCreatedDate() | datetime | When the note was recorded. |
Notes intentionally do not store rendered text. Storing the blueprint key and resolving at read time means that when a source entity changes (for example, a collaborator’s display name is updated), every historical note that mentions that collaborator reflects the change automatically.
Extended fields (REST only, via ?fields=)
These fields are resolved dynamically at request time by the field resolver system and must be explicitly requested.
| Field | Type | Description |
|---|---|---|
renderedContent | string | The note’s blueprint rendered with source data substituted in (for example, Obligation #42 issued for Jane Smith). This is what the activity feed UI displays. |
sourceData | object | The raw data array the blueprint was resolved against. Use this when you want to format notes yourself instead of using renderedContent. |
sources | array | The list of source entities this note is linked to, as {sourceType, sourceId} pairs. A single note typically links to several sources (the conversion, the obligation, and the collaborator all share the same obligation_issued note). |
Blueprint keys
Every note stores a blueprint key in its content field. The blueprint registry maps each key to a template string with {placeholder} tokens, which the resolver system fills in at read time. Siren ships with 22 core blueprints covering the full lifecycle.
| Key | Written when |
|---|---|
obligation_issued | An obligation is created for a conversion. |
obligation_completed | An obligation is rolled into a payout. |
conversion_awarded | A conversion is awarded to a collaborator. |
conversion_approved | A pending conversion is approved. |
conversion_rejected | A conversion is rejected manually or by a refund. |
conversion_renewed | A renewal transaction produces a renewed conversion. |
renewed_conversions_awarded | Renewed conversions are awarded under a program. |
payout_created | A payout record is created for a collaborator. |
payout_paid | A payout is marked as paid. |
fulfillment_created | A fulfillment batch is created. |
fulfillment_status_changed | A fulfillment’s status changes. |
collaborator_account_ready | A collaborator account is activated. |
collaborator_submission_complete | A collaborator application is submitted. |
opportunity_invalidated | An opportunity is invalidated. |
manual_attribution_requested | A transaction is manually attributed to a collaborator. |
program_group_conversion_triggered | A program wins a program-group competition for a transaction. |
engagement_awarded | An engagement is awarded to a collaborator. |
refund_triggered | A refund fires for a transaction. |
coupon_applied | A bound coupon is applied. |
allocation_completed | A distribution allocation is completed. |
distribution_completed | A distributor completes a distribution cycle. |
org_created | A new organization is created (multi-site installs). |
Extensions can register additional blueprints by listening for the NoteBlueprintRegistryInitiated event and calling $event->addNote($key, $resolver).
Source linking
A note is rarely useful on its own. What makes the activity feed work is that each note is linked to every record the underlying event touched. An obligation_issued note is linked to the obligation, the conversion that caused it, and the collaborator who is owed the money. Open any of those three detail screens and the same note appears in the feed.
Source links live in the NoteSources junction table. Each row is a {noteId, sourceType, sourceId} tuple. The supported source types are the major domain records: collaborator, conversion, obligation, fulfillment, payout, engagement, opportunity, transaction, distribution, program, and distributor. Not every note links to every type. A coupon_applied note, for example, links to the opportunity and the collaborator, but not to a conversion, because no conversion exists yet when the coupon is applied.
The REST API exposes notes by source, not by raw note ID. You ask “what notes exist for collaborator 42?” and the response is the list of every note linked to that collaborator in the order the events happened.
Accessing note data
# Fetch the activity feed for an obligation
curl -X GET "https://your-site.com/wp-json/siren/v1/notes?sourceType=obligation&sourceId=42&fields=id,renderedContent,creationSource,dateCreated" \
-H "Authorization: Bearer YOUR_TOKEN"
# Same feed, but return raw source data so you can format it yourself
curl -X GET "https://your-site.com/wp-json/siren/v1/notes?sourceType=obligation&sourceId=42&fields=id,content,sourceData,sources,dateCreated" \
-H "Authorization: Bearer YOUR_TOKEN" use Siren\Notes\Core\Datastores\Note\Interfaces\NoteDatastore;
class ActivityFeedReader
{
protected NoteDatastore $notes;
public function __construct(NoteDatastore $notes)
{
$this->notes = $notes;
}
public function getFeedForObligation(int $obligationId): array
{
return $this->notes->getNotesForSource('obligation', $obligationId);
}
} use Siren\Notes\Core\Facades\Notes;
$feed = Notes::getNotesForSource('obligation', 42); Siren is built on an event-driven architecture. Notes are written by
CreateNoteFor*listeners that respond to lifecycle events. Creating notes by calling the datastore directly bypasses the source-linking logic that makes the activity feed work, so the resulting entries won’t appear in any record’s feed. If you want a note to exist, fire (or add a listener to) the event the blueprint is designed for.
REST endpoints
| Method | Path | Description |
|---|---|---|
| GET | /notes | List notes for a source |
| GET | /notes/:id/position | Get a note’s position in its feed |
See the individual endpoint pages in the sidebar for full request and response details, or browse the all REST endpoints reference.
Relationships
Every note is linked to one or more source records via the NoteSources junction table. Those sources span the full domain model:
- Collaborators — a note is linked to every collaborator mentioned in the underlying event.
- Conversions, Obligations, Fulfillments, Payouts — the payment pipeline records.
- Engagements, Opportunities, Transactions — the attribution records.
- Distributions, Programs, Distributors — the configuration records when the event is scoped to them.
Notes are written as a side effect of the normal event pipeline. If you’re adding a new event to Siren, registering a blueprint for it makes it show up in the activity feed automatically. See the events reference for the full event catalog.