Process a user’s email inbox to extract Venmo and Zelle transaction information and create events in the ledger. User authenticates to the app first (email/password, Google, etc.); inbox access is requested separately via a “Connect email” flow, not at login.
connector.gmail, connector.outlook, etc.) with provider-specific OAuth and fetch logic.UserIdentity for the provider so the user can “Sign in with Google” or “Sign in with Microsoft” in the future. If identity already exists for same user, no duplicate; if exists for different user, reject with conflict.last_at (minus fudge factor) as the boundary for fetching new messages. Deduplicate by excluding already-processed message IDs before creating events.last_at - N (e.g. 5–15 min) to overlap and avoid missing late-arriving messages.external_ids on ledger: Array of namespaced ids, always indexed. Each event can carry multiple ids for different dedup dimensions.external_ids = ['gmail:{message.id}', 'venmo:{transaction_id}'] – message-level (“we processed this email”) and transaction-level (“we saw this Venmo tx”) dedup.external_ids in event references: Include references.external_ids (array) so the ledger preprocessor can dedup generically: if any id in the array already exists on a ledger record, skip.from:venmo.com, subject contains “Zelle”).email).EventCreate with source (e.g. connector.gmail), references.email.message_id, references.external_ids = [f'{provider}:{message.id}', f'{payload_source}:{payload_id}'] (e.g. ['gmail:msg_123', 'venmo:tx_456']). Ledger preprocessor dedupes if any id in the array already exists.@gmail.com → Gmail, @outlook.com → Outlook, etc.). For custom domains (e.g. @modfin.com hosted by Google), use MX lookup or prompt. Always prompt if ambiguous – don’t route silently when uncertain.| Provider | API / Protocol | OAuth |
|---|---|---|
| Gmail | Gmail API | Google OAuth |
| Outlook/Hotmail | Microsoft Graph | Microsoft OAuth |
| Yahoo | IMAP or Yahoo API | Yahoo OAuth |
| iCloud | IMAP | Apple Sign In |
| Generic | IMAP | App passwords |
For generic IMAP, there is no federated identity to link – connector provides mailbox access only, not a new sign-in option.
client_id, client_secret, redirect URIs.https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize with scopes Mail.Read, offline_access, openid, email. Use tenant common for personal (Outlook.com, Hotmail) and work accounts.https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token.https://graph.microsoft.com/v1.0/me/messages.gmail, outlook, etc. (connectors/consts, schemas, routes).external_ids column (array; check for overlap with incoming ids for dedup).source for email connectors; add references.external_ids (array of namespaced ids, e.g. ['gmail:msg_123', 'venmo:tx_456']); ledger preprocessor dedupes if any id already exists.