Skip to content

Constant Contact API

SlothfulDreams edited this page Aug 11, 2025 · 3 revisions

OAuth Integration & Constant Contact Newsletter Fetching


Context

  • NEFAC uses Constant Contact for email newsletters and online publication hosting
  • Current homepage newsletter sections link manually to Constant Contact publications
  • Objective: Automatically fetch newsletters filtered by mailing list (such as Advocacy, Commentary) and render them server-side in Next.js pages
  • No user login to Constant Contact is required; all API calls and authentication happen on the backend
  • OAuth is required for API access

OAuth Authentication: PKCE Flow

How PKCE Flow Works in Our Intended Setup

  1. Authorization request: The app generates a code verifier and corresponding code challenge
  2. User Authorization: The user (usually an admin or developer in a secure environment) is redirected to Constant Contact’s authorization page with the code challenge
  3. Token Exchange: After authorization, the backend receives an authorization code and exchanges it (with the code verifier) for an access token and refresh token
  4. Token Storage: Tokens are stored securely only on the backend
  5. Token Refresh: When the access token expires, the backend uses the refresh token to obtain a new access token automatically
  6. Refresh Token Expiry: Refresh tokens do not expire unless unused for 180 days; each use resets this timer

Note: Since this flow requires user authorization only once (or rarely), a script or admin page can be used to run the OAuth flow and obtain tokens


Token Security & Storage

  • Tokens and secrets are never exposed to frontend users
  • If NEFAC’s backend environment supports secret storage securely (e.g., environment variables or encrypted files), tokens can be stored there
  • Alternatively, use AWS Secrets Manager to store and encrypt refresh tokens and client secrets:
    • Secrets Manager encrypts data at rest and enforces access via IAM roles.
    • Cost around $0.40/secret/month
  • Backend fetches refresh token securely from Secrets Manager or equivalent before refreshing access tokens.

Constant Contact API Usage & Querying

  • Newsletters are categorized by mailing lists (Constant Contact’s "lists" or "contact lists").
  • NEFAC does not use folders, so filtering by mailing list ID is key.
  • Workflow:
    • Query mailing lists via /lists endpoint.
    • Store mapping of mailing list IDs to user-friendly display names
    • Fetch publications filtered by mailing list IDs for each category.
  • Mailing list data can be cached or hardcoded as constants since they rarely change.
  • API docs for lists: https://v3.developer.constantcontact.com/api_guide/lists_get_all.html

Caching Strategy & Rate Limits

Rate Limits

  • 10,000 requests per day (resets midnight EST).
  • 4 requests per second.
  • Burst limits undocumented but rapid bursts may trigger temporary blocks (HTTP 429).

Caching

  • Implement time-based server-side caching for newsletters per category.
  • Cache duration depends on newsletter update frequency.
  • Cache can be stored in-memory or in persistent storage (Redis, file system) depending on deployment.
  • On cache expiry, backend fetches fresh data using stored tokens.
  • Caching reduces load times and helps avoid hitting rate limits.

Summary of Implementation Steps

  1. Manual/one-time OAuth authorization using PKCE to obtain initial tokens.
  2. Securely store access and refresh tokens on backend or AWS Secrets Manager.
  3. Develop backend library/module to:
    • Use stored tokens to fetch newsletters filtered by mailing list.
    • Automatically refresh access tokens when expired.
    • Implement caching with configurable TTL per newsletter category.
  4. Serve cached or fresh newsletter data on server-side rendered Next.js pages.
  5. Maintain a mapping of mailing list IDs to display names in code/config.
  6. Monitor API usage and caching efficiency; adjust caching durations as needed.

Useful Resources


Important things to note

  • Refresh tokens require use at least once every 180 days or they expire

Clone this wiki locally