Version: 1.0.0Documentation Index
Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
Use this file to discover all available pages before exploring further.
Created: 2026-02-23
Updated: 2026-02-24
Status: ποΈ Scaffolded (Phase 1 β gateway integration pending sandbox credentials)
Owner: FA (Finance & Accounting)
Overview
This document defines the integration contract between Encore Health OSβs FA module and Ramp for corporate card and spend management. Ramp provides spend management, corporate cards, ERP/accounting sync (vendors, transaction coding, payables), and an open developer API. This integration enables syncing card transactions into Encore Health OS for coding, approval workflows, and reconciliation.Quick Reference
| I need to⦠| Pattern | Location |
|---|---|---|
| Connect Ramp to Encore Health OS | OAuth callback or API key registration | Edge function ramp-connect; table fa_ramp_connections |
| Sync card transactions | Idempotent sync by Ramp transaction ID | Edge function ramp-sync; table fa_card_transactions |
| Disconnect Ramp | Revoke tokens, set status disconnected | Edge function ramp-disconnect |
| Verify webhook events | Signature verification per Ramp docs | Edge function ramp-webhook; store RAMP_WEBHOOK_SECRET |
Decision Trees / Pattern Library
- OAuth vs API key: Use OAuth when the Connect UX involves user authorization in the browser (recommended per Ramp guide). Use API key for server-only or headless sync when OAuth is not required.
- Pagination: Ramp list endpoints use limit/page or cursor; loop until all pages are fetched for the orgβs date range. See v1/pagination.
- Deduplication: Use
fa_card_transactions.ramp_transaction_idas unique key; unique index on that column. On conflict, skip or update per product requirement (spec recommends skip for idempotency).
Common Mistakes
| Pitfall | Mitigation |
|---|---|
| Skipping webhook signature verification | Always verify signature using RAMP_WEBHOOK_SECRET per v1/api/webhooks; reject unsigned or invalid payloads. |
| Token refresh not handled | Proactively refresh before token_expires_at or reactively on 401; set reauth_required when refresh fails. |
| Duplicate transactions imported | Enforce unique index on fa_card_transactions.ramp_transaction_id; use upsert/skip on conflict. |
| RLS misconfiguration | Use SECURITY DEFINER helpers; ensure UPDATE policies include WITH CHECK on organization_id. |
Pre-Flight Checklist
- Env vars set:
RAMP_CLIENT_ID,RAMP_CLIENT_SECRET,RAMP_API_KEY(if used),RAMP_WEBHOOK_SECRET,RAMP_ENVIRONMENT. - DB index on
fa_card_transactions.ramp_transaction_idfor deduplication. - Test sandbox connection (request access via Ramp partnerships intake) before production.
Integration Pattern
Type: External API Integration via Edge FunctionsDirection: Outbound (Encore Health OS β Ramp) + Inbound (Webhooks if supported by Ramp)
Authentication: OAuth (recommended for Connect UX) and/or API key; see Ramp docs.ramp.com/developer-api/v1/guides/oauth
Authentication Requirements
Environment Matrix
| Environment | Access | Notes |
|---|---|---|
| Sandbox | Request via Ramp partnerships intake | Test data; develop without production credentials |
| Production | API key from Ramp onboarding form | Active Ramp account required |
Credentials
| Credential | Purpose | Storage |
|---|---|---|
RAMP_CLIENT_ID | OAuth app identification | Supabase Secret |
RAMP_CLIENT_SECRET | OAuth app secret | Supabase Secret |
RAMP_API_KEY | Server-to-server API access (if used) | Supabase Secret |
RAMP_WEBHOOK_SECRET | Webhook signature verification (if Ramp provides webhooks) | Supabase Secret |
RAMP_ENVIRONMENT | sandbox | production | Environment variable (non-sensitive config) |
API Endpoints
Ramp API (Outbound)
Reference: docs.ramp.com/developer-api| Area | Purpose | Doc URL |
|---|---|---|
| OAuth | Authorization and token exchange | v1/guides/oauth |
| Transactions | List/sync card transactions; filters: date range, merchant, status | v1/api/transactions |
| Pagination | Cursor-based: page_size (2-100) + start (last entity ID) | v1/pagination |
| Card Programs | List card programs (optional Phase 1) | v1/api/card-programs |
| Webhooks | Push events (e.g. transaction.created); verify signature per docs | v1/api/webhooks |
| Reimbursements | Out of scope Phase 1 | v1/api/reimbursements |
Edge Functions (Inbound/Internal)
| Function | Method | Purpose |
|---|---|---|
ramp-connect | POST | Complete OAuth callback or register API key; create/update org connection |
ramp-sync | POST | Sync card transactions for the organizationβs Ramp connection |
ramp-disconnect | POST | Revoke tokens, set connection status to disconnected |
ramp-webhook | POST | Handle Ramp webhook events; verify signature per v1/api/webhooks |
Transactions Sync (Pagination and Deduplication)
- Pagination: Cursor-based:
page_size(2-100, default 20) +start(ID of last entity). Loop until no more results. See v1/pagination. Confirmed 2026-02-24. - Deduplication: Use Ramp transaction ID as unique key; unique index on
fa_card_transactions.ramp_transaction_id. On conflict (sameramp_transaction_id), either skip or update existing row per product requirement (spec recommends skip for idempotency). - Incremental sync: If Ramp supports filtering by
updated_ator similar, use it to reduce payload; otherwise full date-range fetch with deduplication is acceptable for Phase 1.
Data Flow
Webhook Events
Ramp supports webhooks (see v1/api/webhooks). Implementation must confirm the following from live docs:- Signature verification: Implement per Rampβs webhook docs (e.g. HMAC, webhook secret header, or JWT); store
RAMP_WEBHOOK_SECRETin Supabase secrets. - Replay protection: Use timestamp window if Ramp provides one (e.g. reject if
toutside Β±3 min). - Event types: e.g.
transaction.created, connection/revoked β document exact event names and payload fields when implementing; map to actions below. - Actions: Update connection status, trigger incremental sync, or mark transactions; never log full tokens or card numbers.
- Retries: Ramp retries webhook delivery up to 10 times for 429/5xx responses. Endpoint must respond within 10 seconds. Implement idempotency using event
idto handle duplicate deliveries. Confirmed 2026-02-24.
Database Schema
New Tables
fa_ramp_connections
idUUID PKorganization_idUUID FK, UNIQUE (one connection per org)- Ramp entity/account identifier(s)
- Token columns (encrypted at rest) or reference to secrets
connection_statusTEXT β connected | disconnected | error | reauth_requiredlast_synced_atTIMESTAMPTZcreated_at,updated_at- RLS via SECURITY DEFINER helper on
organization_id
fa_card_transactions
idUUID PKorganization_idUUID FKramp_connection_idUUID FKramp_transaction_idTEXT UNIQUE (deduplication)- Amount, currency, date, merchant, status, etc. (match Ramp API response)
- GL/vendor coding columns (nullable)
created_at,updated_at- RLS on
organization_id - Unique index on
ramp_transaction_id
Modified Tables
fa_module_settings
ramp_integration_enabledBOOLEAN DEFAULT false
Security Considerations
Token Storage
- App-level credentials (
RAMP_CLIENT_ID,RAMP_CLIENT_SECRET,RAMP_WEBHOOK_SECRET) are stored in Supabase Secrets. - Per-organization OAuth tokens (
access_token,refresh_token) are stored in encrypted DB columns scoped byorganization_id(not in shared Supabase Secrets). - Tokens are never exposed to frontend.
- Edge functions access per-org tokens via service-role queries filtered by
organization_id.
Multi-Tenancy
- All Edge Function queries include
organization_idfilter - RLS policies on
fa_ramp_connectionsandfa_card_transactionsenforce organization isolation - Audit logging for connect, sync, disconnect, and webhook events
PHI/PII
- Card transaction metadata (merchant, amount) is not PHI
- Do not send or log PHI to Ramp; do not log full card numbers or tokens
Error Handling
Ramp API Errors
| HTTP Status | Meaning | Action |
|---|---|---|
| 401 | Unauthorized / token invalid | Set status to reauth_required or disconnect |
| 403 | Forbidden / access revoked | Set status to disconnected |
| 429 | Rate limited | Exponential backoff, retry |
| 5xx | Ramp server error | Log, retry with backoff |
Retry Strategy
- Exponential backoff for 429 and 5xx uses
1s, 2s, 4s, 8s, 16s; anyRetry-Afterheader takes precedence. - Do not retry 4xx (except 429) indefinitely.
- Rate limit: 200 requests per 10-second rolling window (confirmed from Ramp docs 2026-02-24). Apply the same backoff sequence above on 429 responses.
- Align with FA-20 Plaid pattern: same backoff array and break on nonβrate-limit errors.
Logging
Allowlisted Fields
organization_idramp_connection_id(not tokens)transactions_synced,transactions_skippedsync_duration_ms- Webhook event type (not payload secrets)
Prohibited
access_token,refresh_token, API keys- Full card numbers or sensitive merchant PII
Testing Strategy
- Unit: Ramp client and transaction mapping (mocked responses); webhook signature verification with test secret.
- Integration: Connect and sync against Ramp sandbox (request access via Ramp Partnerships Intake); test pagination, date-range filter, and deduplication.
- E2E: Connect β Sync β View transactions (when UI exists).
- RLS: Verify tenant isolation on
fa_ramp_connectionsandfa_card_transactions.
Implementation Confirmation Checklist
Before marking integration complete, confirm with live Ramp docs and sandbox:- OAuth: scopes, token refresh, and redirect/callback URL requirements.
- Transactions: exact path, query params (date range, status, limit, page/cursor), response schema; map all required fields to
fa_card_transactions. - Webhooks: event types, payload shape, signature algorithm and header; implement verification and idempotent handling.
- Rate limit: 200 requests per 10-second rolling window (confirmed 2026-02-24); honor
Retry-Afterheader. - Sandbox: request and obtain sandbox credentials; document test entity/card data if provided.
Rollback Strategy
- Feature flag
ramp_integration_enableddisables UI and sync - Disabling flag hides Ramp options; existing data remains; no destructive migration required
- Optional: soft-delete or status column on
fa_ramp_connectionsfor reversible disconnect
References
- Spec: FA-30-ramp-corporate-cards-spend-integration.md
- Ramp Developer API: docs.ramp.com/developer-api
- Ramp OAuth: docs.ramp.com/developer-api/v1/guides/oauth
- Ramp Transactions: docs.ramp.com/developer-api/v1/api/transactions
- Ramp Pagination: docs.ramp.com/developer-api/v1/pagination
- Ramp Webhooks: docs.ramp.com/developer-api/v1/api/webhooks
- Ramp Developer Tools: ramp.com/developer-tools
- FA-12: Expense Management (corporate card integration Phase 2)
- FA_TELLER_INTEGRATION.md: Pattern reference for external FA integration (mTLS, webhooks, edge functions)
- FA-20-PLAID-INTEGRATION.md: Pattern reference for OAuth, Sync API, webhook verification, rate-limit retry