Siren

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

FieldREST namePHP getterTypeDescription
IDidgetId()integerUnique identifier
ContentcontentgetContent()stringThe blueprint key (for example, obligation_issued). The displayable text is resolved from this key at read time.
Creation sourcecreationSourcegetCreationSource()stringThe entity type that caused the note to be written (for example, conversion).
Creation source IDcreationSourceIdgetCreationSourceId()integerThe ID of the entity that caused the note to be written.
CreateddateCreatedgetCreatedDate()datetimeWhen 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.

FieldTypeDescription
renderedContentstringThe 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.
sourceDataobjectThe raw data array the blueprint was resolved against. Use this when you want to format notes yourself instead of using renderedContent.
sourcesarrayThe 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.

KeyWritten when
obligation_issuedAn obligation is created for a conversion.
obligation_completedAn obligation is rolled into a payout.
conversion_awardedA conversion is awarded to a collaborator.
conversion_approvedA pending conversion is approved.
conversion_rejectedA conversion is rejected manually or by a refund.
conversion_renewedA renewal transaction produces a renewed conversion.
renewed_conversions_awardedRenewed conversions are awarded under a program.
payout_createdA payout record is created for a collaborator.
payout_paidA payout is marked as paid.
fulfillment_createdA fulfillment batch is created.
fulfillment_status_changedA fulfillment’s status changes.
collaborator_account_readyA collaborator account is activated.
collaborator_submission_completeA collaborator application is submitted.
opportunity_invalidatedAn opportunity is invalidated.
manual_attribution_requestedA transaction is manually attributed to a collaborator.
program_group_conversion_triggeredA program wins a program-group competition for a transaction.
engagement_awardedAn engagement is awarded to a collaborator.
refund_triggeredA refund fires for a transaction.
coupon_appliedA bound coupon is applied.
allocation_completedA distribution allocation is completed.
distribution_completedA distributor completes a distribution cycle.
org_createdA 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

MethodPathDescription
GET/notesList notes for a source
GET/notes/:id/positionGet 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:

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.