Skip to content

Ramp Integration

Connect your Ramp corporate card account for automated expense categorization, reimbursement tracking, and journal entry creation.

The /api/v1/ramp/* endpoints below work with an API token but are not part of the public API Reference — they back DayZero's own Integrations page and may change. Synced activity lands in the public Journal Entries, Transactions and Bills endpoints, which is where integrations should read from.

What Gets Synced

Data Description
Card transactions Expense journal entries coded to the GL account chosen in Ramp; also shown on the Transactions page
Reimbursements Employee reimbursements booked to Reimbursements Payable
Bills and bill payments Ramp Bill Pay bills pulled into Bills; paid bills posted as payments
Transfers, cashbacks, statements Stored and reported back to Ramp as synced, but not booked as journal entries (the cash movements arrive through your bank feed)
Merchants Merchant name normalization
Receipts Receipt and memo data for audit trail

Connect Ramp

From the Integrations page in DayZero, click Connect with Ramp. You'll be redirected to Ramp to authorize access. The button shows only where DayZero's own Ramp app is set up (the status response's oauth_available); elsewhere the card shows the client-credentials form, and connect-url returns 400 instead of a link Ramp would reject.

Or via API:

bash
curl "https://api.ondayzero.com/api/v1/ramp/connect-url" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

This call needs admin permission. The response includes connect_url and state. Redirect the user to connect_url from the same browser (the call sets a dz_oauth_ramp cookie that the callback requires) to begin the OAuth flow. After authorization, DayZero stores the connection and begins syncing transactions. Add ?card_issuing=true to also request the card-issuing scopes that a credit program needs.

Client credentials (Bring your own Ramp Developer App)

Use this when your business created its own Ramp Developer App (Company → Developer → Create New App) with the Client Credentials grant type enabled.

From the Integrations page, open Advanced: use your own Ramp Developer App (shown directly when OAuth isn't available), enter your Client ID and Client Secret and click Connect Ramp.

Or via API — the body must be a flat JSON object (not wrapped in data):

bash
curl -X POST "https://api.ondayzero.com/api/v1/ramp/connect-with-credentials" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"ramp_id_...","client_secret":"..."}'

Optional "card_issuing": true also asks for the card-issuing scopes. If the app does not allow them, the connection still succeeds and the status reports issuing_scopes_granted: false. Re-sending credentials for the same Ramp business (for example after rotating a secret) updates the connection in place and keeps its sync settings; a healthy connection to a different Ramp business must be disconnected first (400 INTEGRATION_060).

Required Ramp app setup:

  1. Grant type: Client Credentials
  2. Scopes: configure the scopes your integration needs in the Ramp Developer Console (e.g. transactions:read, business:read, cards:read, users:read, departments:read)
  3. Copy the Client ID (ramp_id_...) and Client Secret from the app settings

When Ramp refuses the connection, the endpoint answers with Ramp's own reason rather than a generic failure:

  • 400 INTEGRATION_079 — Ramp rejected the Client ID / Client Secret pair.
  • 400 INTEGRATION_076 — the token was issued but is missing business:read / transactions:read; the message lists the scopes DayZero detected on it.
  • 400 INTEGRATION_080 — Ramp rejected the token request for some other reason (e.g. the Client Credentials grant type is not enabled); the message quotes Ramp's error_description.
  • 503 INTEGRATION_080 — Ramp was rate-limiting or unavailable. Retry.

Automatic Accounting

When a corporate card transaction occurs, DayZero creates journal entries:

  • Card purchase: Debit Expense Account / Credit Ramp Card Payable (a refund books the mirror image)
  • Reimbursement: Debit Expense Account / Credit Reimbursements Payable (the same account approved expense reports accrue to)
  • Bill paid (from the bills.paid webhook): Debit Accounts Payable / Credit Ramp Settlement Account

Each transaction is booked once, however many events or syncs deliver it. Multi-line coding in Ramp becomes a multi-line entry. Settling the card or paying out a reimbursement is a bank movement and comes through the connected bank feed, not through Ramp.

A card issued against a partner credit line (a lender's card program on its Ramp account, managed by DayZero; see Partner Credit Lines) is the exception. Spend on it is the merchant's draw on the line, not the business's own spending: it reaches the credit ledger as a loan from Ramp's webhook whether or not accounting sync is switched on, and it is never stored among the business's Ramp transactions or booked as its expense against Ramp Card Payable, by the webhook or by the scheduled sync (so a journal-entry backfill cannot book it later either). Every other card's transactions are handled as above.

The expense account is the GL account the Ramp user selected when coding the transaction (register DayZero as Ramp's accounting provider, below, so Ramp codes against DayZero's chart of accounts). Spend with no GL coding books to Uncategorized Expense and can be recategorized in DayZero. Booked transactions are also mirrored onto the Transactions page as card activity.

Connection Status

bash
curl "https://api.ondayzero.com/api/v1/ramp/status" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

Returns connected, healthy, needs_reauth (Ramp rejected the stored credentials, so only re-entering the Client ID / Secret clears it), last_synced_at, last_sync_error, transaction_count, the Ramp business name/ID, whether the connection uses_own_credentials, oauth_available (not connected only: whether Connect with Ramp can be offered), a scope_status breakdown (granted vs. missing required, recommended, optional and card-issuing scopes), issuing_scopes_granted and the current sync_config.

Sync Configuration

GET /api/v1/ramp/sync-config returns what is synced and how often; PUT the same shape to change it. Both need admin permission. Every field is optional on update (sync_enabled: false turns the whole accounting sync off and a sync then returns status: sync_disabled; auto_sync_interval_hours is 1-24, default 24; all sync_* type toggles default to on except sync_all_cleared_transactions):

bash
curl -X PUT "https://api.ondayzero.com/api/v1/ramp/sync-config" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "auto_sync_enabled": true,
    "auto_sync_interval_hours": 6,
    "sync_from_date": "2026-01-01",
    "sync_transactions": true,
    "sync_reimbursements": true,
    "sync_bills": true,
    "sync_bill_payments": true,
    "sync_transfers": false,
    "sync_cashbacks": false,
    "sync_statements": false
  }'

Restrict the scope with sync_card_ids, sync_department_ids or sync_user_ids (Ramp IDs — GET /api/v1/ramp/available-filters lists the options), or bound the window with sync_from_date / sync_to_date. By default only transactions Ramp's accounting queue marks sync ready (coded and approved) are pulled; set sync_all_cleared_transactions: true to pull every cleared card transaction — useful for businesses that don't code spend in Ramp. Uncoded rows book to Uncategorized Expense and can be categorized in DayZero.

Manual Sync

Trigger a manual sync (admin permission). It queues a background job that pulls transactions, reimbursements, bills, bill payments, transfers, cashbacks and statements, as allowed by the sync configuration. The same sync also runs automatically: an hourly poller starts a sync for each connection whose auto_sync_interval_hours has elapsed.

bash
curl -X POST "https://api.ondayzero.com/api/v1/ramp/sync" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

POST /api/v1/ramp/bills/sync pulls Ramp Bill Pay bills on their own, and POST /api/v1/ramp/backfill-journal-entries creates journal entries for any already-synced transactions that are missing one. GET /api/v1/ramp/balance returns connected, the card program's current balance and available card limit in cents (card_balance_cents, available_card_limit_cents; both null if Ramp could not be reached, and connected: false when Ramp is not linked), currency and ramp_business_name. All of these need admin permission except balance.

Ramp as an accounting destination

DayZero can also register itself as Ramp's accounting provider so that Ramp users code transactions against DayZero's chart of accounts inside Ramp: POST /api/v1/ramp/accounting/setup registers the provider, POST /api/v1/ramp/accounting/push-coa pushes the chart of accounts, and POST /api/v1/ramp/accounting/mark-synced ({"object_ids": [...], "sync_type": "TRANSACTION_SYNC"} — or REIMBURSEMENT_SYNC, BILL_SYNC, etc.) tells Ramp which objects have been booked. The regular sync does this automatically for what it books.

Webhooks

Nothing to set up: when you connect, DayZero registers a webhook subscription on your Ramp account pointing at its own endpoint and answers Ramp's setup challenge automatically. Ramp issues a signing secret per subscription, so each business that brings its own Developer App gets its own. Disconnecting removes the subscription.

If your Ramp app can't manage webhooks, connecting still succeeds — the integration falls back to scheduled polling, just with more delay before a transaction appears.

DayZero processes the following Ramp webhook events in real time:

Event Action
transactions.authorized, transactions.cleared, transactions.ready_for_review, transactions.ready_to_sync Store the transaction and, unless it falls outside the sync filters (card, user, department, date range), create the expense journal entry once; later events for an already booked transaction change nothing. On a card that belongs to a partner credit line nothing is stored or booked as the operator's expense: a cleared purchase becomes a loan on the line instead, and Ramp's other transaction events for it are ignored
transactions.declined On a partner-credit card, puts the loan of a transaction already recorded as cleared on a void hold; ignored otherwise
bills.created, bills.approved, bills.rejected Acknowledged only; bills are pulled by the scheduled sync and POST /api/v1/ramp/bills/sync
bills.paid Creates the bill payment journal entry (Debit Accounts Payable / Credit Ramp Settlement Account), once per Ramp bill

Transaction events are ignored when the transactions toggle is off in the sync configuration, bill events when bills are off, and everything except credit-line routing when sync_enabled is false.

Ramp webhook payloads carry only the resource ID, so DayZero fetches the full record from the Ramp API when an event arrives. Events may arrive out of order and are retried up to 10 times; DayZero de-duplicates on the event id.

Disconnect

bash
curl -X DELETE "https://api.ondayzero.com/api/v1/ramp/disconnect" \
  -H "Authorization: Bearer dz_your_token_here" \
  -H "x-business-id: YOUR_BUSINESS_ID"

Removes stored credentials and disconnects the Ramp integration from the business.