Introduction to Ramp Accounting API
This guide walks you through the process of connecting your ERP to Ramp via Ramp Accounting API
Overview
Ramp Accounting API is built to empower you to streamline your accounting workflow even if you use an ERP for which Ramp does not have direct integration coverage.
At a high level, Ramp Accounting API allows you to:
- Sync your accounting categories (such as general ledger accounts, vendors and other custom accounting fields) from your ERP to Ramp; with these accounting fields, you can code your transactions on Ramp.
- Fetch transactions with their accounting codings so that you can sync them to your ERP.
- Report sync status back to Ramp after you sync transactions to your ERP; this ensure the data in your Ramp account stays consistent with your ERP.
Integration Guide
Now let's walk through all the steps of building an API-based integration between your ERP and Ramp.
You need to create an App and go through the Authorization first.
Register an accounting connection
The first thing you need to do is to register an accounting connection. Having an accounting connection is a prerequisite for any form of integration between Ramp and a ERP.
In Ramp, there are two types of accounting connections:
- Indirect connection. This type connection relies on customers to sync data between Ramp and their ERP system through our Accounting API or file exchange (CSV).
- Direct connection to an ERP systems. Currently Ramp offers direction integration with NetSuite, Sage, QuickBooks Online and Xero. Note that you cannot access Accounting API if you currently have a direct connection.
To register a new indirect accounting connection, call POST developer/v1/accounting/connection with the name of the ERP system that you use.
import requests
url = "https://api.ramp.com/developer/v1/accounting/connection"
payload = {
"reactivate": False,
"remote_provider_name": "ACCOUNTING_SEED"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
By registering an accounting connection, you are telling Ramp that you intend to enable Ramp Accounting API to perform your accounting workflow.
Note that if you had an accounting API connection before, you could potentially reactivate it by using the reactivate
flag in the request body.
The accounting connection is the cornerstone of your accounting integration so it is important to understand it thoroughly. Most notably, there are two restrictions with the accounting connection that you need to be aware of:
- You can only have one active accounting connection
This means that if you already have an active accounting connection, then you need to disconnect it first before you call POST developer/v1/accounting/connection to register a new one. - All accounting assets are tied to an accounting connection
All accounting assets exist within the context of a specific accounting connection. As a result, after you switch to a new connection, you will lose access to the general ledger accounts, vendors and custom accounting fields of your previous connection.
With that said, it is best to think through the migration plan and thoroughly test your accounting integration in the sandbox environment before you promote it to production.
Upload accounting categories
Now that you have an active accounting connection, the next step is to upload the accounting categories into Ramp. There are four different types of accounting categories within Ramp:
- General Ledger Account
- Vendor
- Subsidiary
- Custom Field
General Ledger Account, Vendor and Subsidiary are predefined by Ramp; below are sample requests to upload these accounting categories:
import requests
url = "https://api.ramp.com/developer/v1/accounting/accounts"
payload = { "gl_accounts": [
{
"classification": "EXPENSE",
"code": "6410",
"id": "514",
"name": "Employees:Salaries & Wages"
},
{
"classification": "EXPENSE",
"id": "418",
"name": "Office/Admin:Phone & Internet"
},
{
"classification": "REVENUE",
"id": "425",
"name": "Sales"
}
] }
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
import requests
url = "https://api.ramp.com/developer/v1/accounting/vendors"
payload = { "vendors": [
{
"id": "V-5500-0130",
"name": "AirTable"
},
{
"id": "V-5500-0135",
"name": "Slack Technologies, LLC"
},
{
"id": "V-5500-0142",
"name": "Microsoft"
}
] }
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
import requests
url = "https://api.ramp.com/developer/v1/accounting/subsidiaries"
payload = { "subsidiaries": [
{
"id": "1418",
"name": "Ramp B.V."
},
{
"id": "1425",
"name": "Ramp LP"
},
{
"id": "1514",
"name": "Ramp Inc."
}
] }
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
Custom Fields are defined by customers. To upload custom field data, you need to define the custom field first:
import requests
url = "https://api.ramp.com/developer/v1/accounting/fields"
payload = {
"id": "Department",
"input_type": "SINGLE_CHOICE",
"is_splittable": "True",
"name": "Department"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
The response from above contains the id of the newly defined field. You can grab that id and upload the options for that field:
import requests
url = "https://api.ramp.com/developer/v1/accounting/field-options"
payload = {
"field_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
"options": [
{
"id": "418",
"value": "Engineering & Design"
},
{
"id": "514",
"value": "Sales & Marketing"
}
]
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
Code transactions
After you upload accounting categories, you should be able to see them on the Ramp Accounting Dashboard and use them to code transactions and mark transactions as "ready to sync":

Fetch transactions
To sync transactions to your ERP system, you need to fetch those transactions along with accounting codings. You can do that by calling GET developer/v1/transactions:
import requests
url = "https://api.ramp.com/developer/v1/transactions/?sync_ready=true&has_no_sync_commits=true"
headers = {
"accept": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.get(url, headers=headers)
Here's a sample response:
{
"accounting_field_selections": [
{
"category_info": {
"external_id": "Category",
"id": "0c0d0bcc-8716-4e05-a651-4ad5e64d2b3e",
"name": "Category",
"type": "GL_ACCOUNT"
},
"external_id": "Category",
"id": "07b4ce4d-2750-412e-aef4-6b7815f1411c",
"name": "Category",
"type": "GL_ACCOUNT"
}
],
"amount": 90,
"card_holder": {
"department_id": "d471d830-2e73-4082-8a75-68540f83e86e",
"department_name": "Executive",
"first_name": "Patrick",
"last_name": "Robinson",
"location_id": "4fcf3423-a2e6-42f6-8dd8-9b3a8c51e069",
"location_name": "San Francisco",
"user_id": "a26c82c9-6b7d-4022-bc4b-a55b4c4743c7"
},
"card_id": "6bc41b14-f853-4862-bae5-4f122f123f6e",
"currency_code": "USD",
"disputes": [],
"id": "fd14cd6a-846e-4994-9315-5a59e6bb465f",
"line_items": [
{
"accounting_field_selections": [
{
"category_info": {
"external_id": "Subsidiary",
"id": "15e9565d-7e73-40d8-9fbc-5f6f89b1c075",
"name": "Subsidiary",
"type": "SUBSIDIARY"
},
"external_id": "425",
"id": "07b4ce4d-2750-412e-aef4-6b7815f1411b",
"name": "Ramp LP",
"type": "Subsidiary"
}
],
"amount": {
"amount": 4000,
"currency_code": "USD"
}
},
{
"accounting_field_selections": [
{
"category_info": {
"external_id": "Subsidiary",
"id": "15e9565d-7e73-40d8-9fbc-5f6f89b1c075",
"name": "Subsidiary",
"type": "SUBSIDIARY"
},
"external_id": "426",
"id": "07b4ce4d-2750-412e-aef4-6b7815f1411a",
"name": "Ramp BV",
"type": "SUBSIDIARY"
}
],
"amount": {
"amount": 5000,
"currency_code": "USD"
}
}
],
"memo": null,
"merchant_category_code": null,
"merchant_category_code_description": null,
"merchant_descriptor": "VANTA",
"merchant_id": "2907e304-cac2-4abf-84c4-b3b454ae3b8c",
"merchant_name": "Vanta",
"original_transaction_amount": {
"amount": 9000,
"currency_code": "EUR"
},
"policy_violations": [],
"receipts": [],
"sk_category_id": 40,
"sk_category_name": "SaaS / Software",
"state": "CLEARED",
"user_transaction_time": "2022-05-03T00:00:00.000000"
}
The accounting related information can be found in:
accounting_field_selections
-- this shows the top level accounting coding of the transactionline_items
-- this shows the accounting codings for each line, if the transaction is split into multiple line items- You may also see
accounting_categories
-- that is the legacy representation of transaction accounting data. It does not provide more information and you can safely ignore it
Sync transactions to your ERP
With the transaction and accounting data gathered from the previous step, you should be able to sync those transactions to your ERP. This step is entirely defined by you.
Report sync status to Ramp
For each transaction synced in the previous step, we want to record the sync status (success or failure) and report back to Ramp. This way we can ensure that your ERP and Ramp are on the same page. You can do that by calling POST developer/v1/accounting/syncs:
import requests
url = "https://api.ramp.com/developer/v1/accounting/syncs"
payload = {
"failed_syncs": [
{
"error": { "message": "The account period has closed and the account books cannot be updated." },
"id": "d471d830-2e73-4082-8a75-68540f83e86e"
}
],
"idempotency_key": "d471d830-2e73-4082-8a75-68540f83e86e",
"successful_syncs": [
{
"id": "5a58eb94-a583-458f-810d-c794f32f2f90",
"reference_id": "d8573713-a97d-4119-bdd7-b69c318df9bb"
},
{
"id": "bb037f47-c664-46f9-afa7-cc68cbcf5a23",
"reference_id": "83283a15-c0a0-4105-9724-2fcfefa9924f"
}
],
"sync_type": "TRANSACTION_SYNC"
}
headers = {
"content-type": "application/json",
"authorization": "Bearer <your_token>"
}
response = requests.post(url, json=payload, headers=headers)
Updated 3 months ago