Version

Core API

The contracts a connector calls into the core — how they are bound, the records and refs that cross them, the idempotency every write keeps, the exceptions, and what the eleven contracts cover.

Ports are the core calling the connector. The Core API is the inverse: interfaces under Subscriby\Connector\Core\* that the application implements and binds in its container, and that a connector calls instead of importing application classes. A core refactor that keeps the contract breaks no connector, and a connector never touches a table it does not own.

Getting hold of a contract

Ask for the interface in a constructor. The application's connector service provider binds each one to its implementation, so any class the container builds (a port, a handler, a job in your package) receives it:

use Subscriby\Connector\Core\Identities;
use Subscriby\Connector\Core\Installations;

final class ExampleInboundController
{
    public function __construct(
        private readonly Installations $installations,
        private readonly Identities $identities,
    ) {}
}

The eleven contracts

ContractReadsWrites
InstallationsBy id, platform id or your storage ref; a project's or the platform's list; the stored credentials of one you can name.record() an installation, recordState() a health verdict, forget() one.
IdentitiesBy id or platform id; who holds an identity (creator, member).record() an identity, link it to a creator or a member, complete a handshake.
SpacesBy id, or by installation, kind and platform id.record() a place, bindResource() an existing resource to it.
ResourcesBy id, by place, or a project's list on your connector.create() the resource that sells a place the creator picked.
GrantsBy id, or by the reference you issued.record() a grant (migration and legacy mirroring).
Creators—register() an email-first creator account from a connector's sign-up; isEmailTaken() to refuse a taken address at the step it is typed.
AlertsWhether a creator's alerts reach one of their accounts.Switch that account on or off for every alert class.
RecoveryWhat the application keeps ready for a project's recovery on your connector.registerStandby() a reserve place for a resource, replaceSpace() the place it lost.
SupportWhether a project takes support messages; the thread behind a relay ping, a quoted relay message or a relay-space thread; the project's relay target.ingest() a member's message, reply() with a creator's answer written on the platform, linkRelaySpace() / unlinkRelaySpace().
ReferralsThe live Referral Program in the core's words; a member's standing with their code, links and tallies; the links they share.join() the programme, capture() a friend who arrived through a deep link or typed a code at checkout, updatePayoutDetails() where to pay them.
ReferralManagementThe options a setup needs; the programme in the core's words with its figures; affiliates by standing with their balances and payout details; members by search.saveProgram() from a draft, setProgramActive(), deleteProgram(), approveAffiliate(), suspendAffiliate(), enrolMember(), recordPayout().
PartnerProgramA creator's standing in the platform's Partner Program in the core's words; their referrals, commissions and payouts paged; their commitments; the payout rails and what each needs.submitProof() on a commitment, addCommitment() on a declared or a new audience, updatePayoutDetails() from a draft, acceptTerms().

Refs and records

Two families of value object cross the boundary:

  • Refs (InstallationRef, IdentityRef, SpaceRef, ResourceRef, GrantRef, ProjectRef, CreatorRef, MemberRef, HandshakeRef) name a row the core already has: its UUID, the external id and, where you keep a row of your own, your storageRef. The core hands them to your ports and the Core API hands them back from every read and write.
  • Records (InstallationRecord, IdentityRecord, SpaceRecord, GrantRecord, CreatorRegistration) describe what the core should write. Every record() is idempotent on the natural key the page names: a second record of the same bot, account, place or grant updates the row rather than adding one, so a connector may record on every event and on every deploy.

Eloquent models never cross. A ref carries what a port needs to act; when a port needs more than a ref holds, the answer is a new field on the ref or a new read on the contract, never a query.

Exceptions

ExceptionThrown byFactories
Subscriby\Connector\Exceptions\HandshakeRefusedIdentities::completeHandshake()expired(), identityHeld(), purposeNotSupported(), installationMismatch()
Subscriby\Connector\Exceptions\RegistrationRefusedCreators::register()emailTaken(), accountRefused()
Subscriby\Connector\Exceptions\ResourceRefusedResources::create(); the recovery writes that name a resource.kindOutsidePlace(), placeUnknown(), projectUnknown(), resourceUnknown(), notPermitted(); read $reason.
Subscriby\Connector\Exceptions\RecoveryRefusedRecovery::registerStandby(), Recovery::replaceSpace()because(); read $reason and relay userMessage(), the core's translated sentence.
Subscriby\Connector\Exceptions\SupportRefusedSupport::ingest(), Support::reply(), the relay-space writes.conversationUnknown(), projectUnknown(), installationUnknown(), spaceUnknown(), notPermitted(); read $reason.
Subscriby\Connector\Exceptions\ReferralRefusedReferrals::join(), Referrals::capture(), Referrals::updatePayoutDetails(); every ReferralManagement call.withReason(), installationUnknown(); read $reason and relay getMessage(), the core's translated sentence.
Subscriby\Connector\Exceptions\ConnectorNotRegisteredA contract asked about a connector key the registry lacks.—

Every other refusal is a null read: a find*() that answers null means the core knows no such row, and the connector decides what that means for the event in hand.

What the contracts cover

Installations, identities, spaces, resources, grants, creator registration, alert routing, recovery coverage with the standby and replacement writes, the support inbox in both directions and the Referral Program as a member meets it and as a creator runs it. Everything a connector does against the core goes through these eleven contracts, and the tutorial walks the calls in the order a connector makes them.

Authorisation is the core's

Every write on the Core API applies the same rules as the dashboard action behind it: a creator who may not link an identity to another creator's account is refused with the same exception whether they try on the web or from a chat. Your connector never checks a permission; it presents the facts and reads the answer.

How is this guide?

Last updated on

Version

On this page

Subscriby is a product
designed by you — for you.
No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request

For AI agents: llms.txt · llms-full.txt