Profiles
A profile is a named set of responsibilities a provider promises to handle. It helps you answer “does this service do the part I need?”
For example, a purchase-checking service may offer verification. A backend that also owns user access needs account lifecycle and entitlements. A service can offer several profiles; you do not need a separate company for each one.
Four responsibilities#
Is the store evidence valid?
Checks a store purchase without assigning it to an app account.
A verification service can specialize in checking purchases while another service owns user access.
Compare the example and IAPKit
Same question: is the evidence valid?
See the service implementationIAPKit
The handler sends evidence to the Apple, Google, Meta, or Amazon verifier and returns the same isValid answer. Store-specific work stays behind this call.
Read code: verifyPurchaseVerdict How to check this behavior
Example. The Verify step checks isValid and confirms that Alice still has no access. Run npm test. Inspect reference
IAPKit. The route suite checks unreachable verification and retry behavior using mocked store I/O. Inspect reference
Contract name: verification
Version 1.0. verifyPurchase
Whose purchase is it?
Connects purchases to your users and removes their identity when requested. Both binding and erasure are required.
Alice owns her purchase. Bob cannot take it. Deleting Alice also removes her identity from the provider’s records.
Compare the example and IAPKit
Delete the account in both implementations
See the service implementationIAPKit
eraseUser starts a project-scoped job. The worker removes identity from purchases, subscriptions, and events in batches, waiting for claimed deliveries before cleaning those events.
Read code: drainSubscriptionUserErasurePage How to check this behavior
Example. Run bun verify-erasure.mjs. It checks active-account erasure, in-flight delivery, repeated jobs, late events, and restart. Inspect reference
IAPKit. Erasure request tests cover server authorization and repeated requests, including already completed jobs. Inspect reference
Contract name: accountLifecycle
Version 1.0. bindPurchase · eraseUser
What can this user use now?
Returns current subscription status and allowed products without exposing purchase tokens.
Alice keeps Premium after turning renewal off and loses access at the end of her paid time.
Compare the example and IAPKit
Same access rule, different storage
See the service implementationIAPKit
isEntitledAt applies the same rule to Convex records. entitlementsV2 reads the current time and returns allowed products without exposing store purchase tokens.
Read code: isEntitledAt How to check this behavior
Example. The state checks test before, at, and after expiry with a controlled clock. Run npm test. Inspect reference
IAPKit. Account-read tests check token omission, server authorization, and time advancing past expiry. Inspect reference
Contract name: entitlements
Version 1.0. subscriptionStatus · entitlements
How does my backend hear about changes?
Sends subscription and access changes as signed webhook messages, with retry rules.
Your backend or data service receives the same event meaning regardless of which compatible provider sent it.
Compare the example and IAPKit
Retries keep one inbox entry
See the service implementationIAPKit
The delivery worker sends signed events to registered backend HTTPS endpoints and records attempts. Your receiver owns duplicate handling; the example shows how to build that side.
Read code: deliverPendingEventsHandler How to check this behavior
Example. Checks cover signatures, retries, tampering, and reopening the inbox. Run npm test or npm run demo:consumer. Inspect reference
IAPKit. Worker tests check signed requests, transport failures, and destination validation with test I/O. Inspect reference
Contract name: events
Version 1.0. Event and webhook obligations
Choose by responsibility, then check the promise
Every provider supports basic discovery, shared errors, and version rules. That common foundation is called core; it is not another optional profile.
The provider lists its complete profiles in capabilities. An unfinished profile must not be advertised. Conformance checks test the promise against the contract.
An analytics service that only receives events follows the receiver rules. It does not have to implement the provider’s events profile or a purchase backend.
Full obligations and independent profile versions: SPEC.md §3.