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 thirty 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 thirty 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; updateSettings() your own declared fields, runAction() one of your installation actions as the creator. A project's installations with their state, as the creator, through detailsForProject(). updateSettingsAs(), the same write as the creator a surface names.
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; a project's resources with their standing, as the creator.create() the resource that sells a place the creator picked, createAs() the same as the creator a ref names; setActive() and delete() one as the creator.
ProjectsA creator's projects, and one with its settings, as the creator.create() from a draft, update() the fields named, delete().
PlansThe options a plan draft picks from; a project's plans and one plan in the core's words, as the creator.create() a subscription plan from a draft, update() the fields named, setPublished(), delete().
CouponsA project's coupons, as the creator.create() from a draft, setActive(), delete().
AccessCodesWhat a batch would cost; a plan's codes, masked.generate() a batch delivered to the creator on their account, revoke() a code.
BroadcastsThe audiences with their sizes; the reach of a draft.send() a draft the creator confirmed, through every live installation.
PaymentSetupThe gateways on offer with the keys each needs; a project's methods, as the creator.configure() a gateway from its keys, onboardingUrl() for one that onboards, setActive(), delete().
CreatorTasksA project's creator tasks by state, as the creator.complete() one, which issues the grant and tells the member.
PassRosterThe Pass Roster one date at a time, as the creator: the plans that sell dates, a plan's coming dates with their roll call, a date's holders with where each stands, and one pass's trail of moves.Read-only.
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.
CreatorSessions—signIn() the creator who holds an account the platform vouched for, from the connector's own login door; a second factor is a challenge, a stranger is unknown.
MembershipsWho an account is in the installation's project and the live memberships they hold, in the core's words.reissueGrants() what the member is owed. The member's recovery email: recoveryEmailOf(), setRecoveryEmail(), resendRecoveryEmailVerification(), removeRecoveryEmail().
StorefrontThe plans on offer to an account by the core's rule, each with the portal checkout that opens it; the portal's address.redeemAccessCode(), the one purchase that completes on a connector; startHostedCheckout(), a gateway's page for a member who picked the rail on the connector.
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, completeRelink() the recovery handshake with the account a creator proved on your platform, openRelink() the handshake opened from a creator surface, incidentsFor() the creator's open incidents, registerStandbyAs() and replaceSpaceAs() the two writes as the creator a surface names, mirrorPairs() the places it mirrors with their standbys, recordMirrored() the stamp of a copy.
Access WindowsThe dated windows of access on an installation's places that have not ended, up to a horizon, once per gated place on your connector: the catch-up read beside the live AccessWindowChanged announcements.Read-only: listUpcoming().
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(). As the creator: inboxFor(), messagesOf(), resolve(), reopen().
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().
PaymentMethods—Rewrites a payment method's stored provider to the connector's own key, the one write a connector's migration makes.
SmartLinksA project's Smart Links with their figures; one link's funnel and addresses, as the creator.arrive() credits a member who opened the installation through a via_<code> deep link, under the core's attribution rule.
RetentionThe cancellation screen as a member meets it; the plan a sequence step reopens.recordCancellationFeedback(), takeOffer(), declineOffer(), recordCheckoutStart(), arriveFromSequence(), stopSequences().
RetentionManagementA project's Revenue Recovery settings with their bounds and coupons, as the creator.saveSettings() from a draft, one field at a time.
PortalDesignA project's portal design as the creator edits it: the draft beside the published design, every choice with its label and options, the signed preview address.saveDraft() from a draft that names only what changed, publish(), discardDraft(), resetSection().
CopilotWhere a creator stands with Subscriby Copilot: the role, the free turns left, the credit.ask() a message, which opens your display and runs the turn on the queue; decide() a confirmation card.
InboundEvents—accept() an event a socket delivered, once per key, before it is queued; a webhook connector never calls it, the inbound middleware does.

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(), Recovery::completeRelink()expired(), identityHeld(), purposeNotSupported(), installationMismatch(), sameIdentity()
Subscriby\Connector\Exceptions\RegistrationRefusedCreators::register()emailTaken(), accountRefused()
Subscriby\Connector\Exceptions\ResourceRefusedResources::create(), the creator's reads and writes on Resources; the recovery writes that name a resource.kindOutsidePlace(), placeUnknown(), projectUnknown(), resourceUnknown(), creatorUnknown(), notPermitted(); read $reason.
Subscriby\Connector\Exceptions\ProjectRefusedEvery Projects call.withReason(); read $reason (creator_unknown, project_unknown, invalid, tier_required, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\PlanRefusedEvery Plans call.withReason(); read $reason (creator_unknown, project_unknown, plan_unknown, invalid, tier_required, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\CouponRefusedEvery Coupons call.withReason(); read $reason (creator_unknown, project_unknown, coupon_unknown, invalid, tier_required, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\AccessCodesRefusedEvery AccessCodes call.withReason(); read $reason (creator_unknown, plan_unknown, code_unknown, invalid, batch_in_flight, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\BroadcastRefusedEvery Broadcasts call.withReason(); read $reason (creator_unknown, project_unknown, no_connection, invalid, tier_required, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\PaymentSetupRefusedEvery PaymentSetup call but providers().withReason(); read $reason (creator_unknown, project_unknown, method_unknown, provider_unknown, invalid, already_configured, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\CreatorTasksRefusedEvery CreatorTasks call.withReason(); read $reason (creator_unknown, project_unknown, task_unknown, invalid, not_permitted) and relay getMessage().
Subscriby\Connector\Exceptions\InstallationRefusedInstallations::updateSettings() and runAction(); the installation connect when the credentials are held or the platform refused.withReason(), credentialsHeld(), byPlatform(); read $reason (creator_unknown, installation_unknown, project_unknown, not_connected, action_unknown, invalid, not_permitted, credentials_held, platform_refused).
Subscriby\Connector\Exceptions\RecoveryRefusedRecovery::registerStandby(), Recovery::replaceSpace()because(); read $reason and relay userMessage(), the core's translated sentence.
Subscriby\Connector\Exceptions\CheckoutRefusedStorefront::startHostedCheckout()withReason(); read $reason (installation_unknown, member_unknown, plan_unknown, method_unknown, provider_unsupported, not_eligible, coupon_refused, gateway_refused) and relay getMessage() for the last three, the core's sentence for the member.
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\CopilotRefusedEvery Copilot call.withReason(), creatorUnknown(), actionUnknown(), surfaceUnavailable(); 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, the dashboard sign-in from a connector's own login door, a member's standing and the plans on offer for a connector's member surface, alert routing, recovery coverage with the standby and replacement writes, the support inbox in both directions, the Referral Program as a member meets it and as a creator runs it, the Partner Program, Smart Links, Revenue Recovery on both sides, the payment-method rewrite, a project's payment methods set up from a creator surface, the inbox and the creator tasks as a creator surface reads them, the Pass Roster one date at a time as a creator surface walks it, a member's recovery email, the dated windows of access a connector mirrors onto its platform, Subscriby Copilot in the creator's chat and the dedupe gate a socket-fed connector records its events through. Everything a connector does against the core goes through these thirty 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