portfolIQ
Documentation

Email notifications

How portfolIQ sends emails — provider, templates, opt-out, and disclaimer policy.

Email notifications

portfolIQ sends transactional and notification emails for authentication, API key lifecycle, quota warnings, incident alerts, and billing events.

Provider

  • Resend (resend.com) — EU region (Frankfurt), GDPR-compliant.
  • From address: noreply@portfoliq.io
  • Reply-to: support@portfoliq.io
  • DKIM, SPF, and DMARC configured on portfoliq.io.

Templates

Templates are React Email components rendered server-side in the Next.js BFF, then dispatched via Resend SDK.

TemplateTypeTriggerLocales
MagicLinkTransactionalMagic link authEN, FR
ApiKeyCreatedTransactionalNew API key createdEN, FR
PasswordResetTransactionalPassword reset requestEN, FR
QuotaWarningNotificationAPI usage at 80%, 95%, 100% of monthly quotaEN, FR
IncidentAlertNotificationIncident posted on status pageEN, FR
InvoicePaidBillingStripe invoice.payment_succeededEN, FR
InvoiceFailedBillingStripe invoice.payment_failedEN, FR

Locale is detected at signup via the Accept-Language header and stored in your account settings. Override it anytime at /account/email-preferences.

Preferences and opt-out

Manage your email preferences at /account/email-preferences.

Four categories can be toggled independently:

  • Product updates — feature releases and changelogs
  • Newsletter — market context and data insights
  • Promotions — plan offers and discounts
  • Recommendations — signal digests (M9+)

Transactional emails cannot be opted out. Password reset, invoice receipts, and API key notifications are required for service delivery and are always sent regardless of preferences.

GDPR: opt-out requests are processed immediately and logged to api.email_unsubscribe_log for audit. One-click unsubscribe via HMAC-signed token (no login required) is included in every marketing and notification email.

portfolIQ applies explicit opt-in for all marketing email categories (GDPR art. 7 / ePrivacy Directive).

Default state at signup

CategoryDefaultLegal basis
NewsletterOffExplicit opt-in required
PromotionsOffExplicit opt-in required
Product updatesOnContract execution (art. 6.1.b)
RecommendationsOnContract execution (art. 6.1.b)

Marketing categories (newsletter, promotions) are never enabled by default — no pre-ticked boxes. A user who does not actively check the opt-in box at signup will have newsletter=FALSE and promotions=FALSE in their preferences row, with consent_marketing_at = NULL.

When a user opts in at signup, the following is recorded in api.user_email_preferences:

ColumnValue
newsletterTRUE
consent_marketing_attimestamp of consent (UTC)
consent_marketing_sourcesignup-form

Accepted values for consent_marketing_source: signup-form, preference-page, support, import.

The user can revoke marketing consent at any time via /account/email-preferences. Revocation is immediate, logged to api.email_unsubscribe_log, and irreversible from the platform side (the user must actively re-opt-in).

B2B note

For B2B API consumers (M12+ tiers), the legal basis for product_updates and recommendations may shift to legitimate interest (art. 6.1.f) once personalisation features are active. This will be re-evaluated at M9 with expert-legal.

Financial disclaimer policy

Per AMF methodology disclosure requirements, emails that may reference market data carry a footer:

Not financial advice. Methodology disclosed. See /docs/core-concepts/methodology for sources and limitations.

TemplateDisclaimer
MagicLinkYes
ApiKeyCreatedYes
QuotaWarningYes
IncidentAlertYes
PasswordResetNo
InvoicePaidNo
InvoiceFailedNo

Deliverability

  • Transactional emails: typical delivery under 5 seconds.
  • Hard bounce or spam complaint: users.email_status is updated automatically — no further sends to that address.
  • Deliverability issues: contact support@portfoliq.io.

Architecture

Python service (api/services/email.py)

    │  POST /api/internal/email/send  (X-Internal-Token, Docker network only)

Next.js BFF (web/app/api/internal/email/send/route.ts)
    │  ① Renders React Email template (HTML + plain text)
    │  ② Calls Resend SDK with idempotency key
    │  ③ Logs to api.email_log

Resend → recipient

    │  Webhook on bounce / complaint / delivered

Next.js POST /api/webhooks/resend  (Svix signature verification)
    │  Updates email_log.status + users.email_status + email_unsubscribe_log

See also

Not financial advice. Methodology disclosed.