API Documentation
The Arvo REST API lets you read and write your CRM data — leads, contacts, companies, deals, quotes, invoices, jobs and more — from any external system, script, or automation tool (Zapier, Make, n8n, your own app). Everything is scoped to your business and respects your validation rules and automations.
It's a standard JSON-over-HTTPS API: predictable resource URLs, standard verbs (GET, POST, PATCH, DELETE), and JSON request/response bodies.
Authentication
Authenticate every request with an API key. Create one under Settings → API Keys (the key is shown once — store it securely; treat it like a password). Pass it as a Bearer token or an X-API-Key header.
# Either header works:
Authorization: Bearer ak_your_key_here
# or
X-API-Key: ak_your_key_here
Keys are scoped to one business. Revoking a key in the dashboard immediately stops all requests using it.
Base URL & objects
All endpoints are under:
https://arvocrm.up.railway.app/api/v1
Available objects (use the name as the URL path):
leads · contacts · companies · deals · quotes · invoices · jobs · tasks · activities · notes · products
Any custom object you create in the Object Builder is also available by its API name.
GET List records
GET /api/v1/:object?limit=100&offset=0
| Query param | Description |
|---|---|
limit | Max records to return (default 100, max 500). |
offset | Skip N records — for pagination. |
Example:
curl -H "Authorization: Bearer ak_xxx" \
"https://arvocrm.up.railway.app/api/v1/leads?limit=50"
Response:
{
"object": "leads",
"count": 2,
"records": [
{ "id": "1a2b…", "name": "Jane Doe", "email": "jane@x.com", "status": "New", … },
{ "id": "3c4d…", "name": "John Smith", "status": "Contacted", … }
]
}
GET Get one record
GET /api/v1/:object/:id
curl -H "Authorization: Bearer ak_xxx" \
"https://arvocrm.up.railway.app/api/v1/contacts/1a2b3c4d"
Returns the full record object, or 404 if it doesn't exist in your business.
POST Create a record
POST /api/v1/:object
Send a JSON body of field → value. Validation rules apply; automations, flows and webhooks fire just like in the app.
curl -X POST "https://arvocrm.up.railway.app/api/v1/leads" \
-H "Authorization: Bearer ak_xxx" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"status": "New",
"source": "Website"
}'
Returns 201 with the created record (including its id). If a name isn't supplied, one is derived from first/last name or email.
PATCH Update a record
PATCH /api/v1/:object/:id
Send only the fields you want to change.
curl -X PATCH "https://arvocrm.up.railway.app/api/v1/deals/9f8e7d" \
-H "Authorization: Bearer ak_xxx" \
-H "Content-Type: application/json" \
-d '{ "stage": "Won", "status": "won" }'
DELETE Delete a record
DELETE /api/v1/:object/:id
curl -X DELETE "https://arvocrm.up.railway.app/api/v1/tasks/5a6b7c" \
-H "Authorization: Bearer ak_xxx"
Returns 204 No Content on success.
Inbound webhooks
Prefer to push data in (e.g. from a website form) without an API key? Create an Inbound Webhook — you'll get a unique URL that maps posted JSON straight into a record:
curl -X POST "https://arvocrm.up.railway.app/api/in/in_yourtoken" \
-H "Content-Type: application/json" \
-d '{ "first_name": "Sam", "email": "sam@example.com" }'
No auth header needed — the token in the URL is the credential. Configure field mapping per endpoint in the dashboard.
Errors & limits
| Status | Meaning |
|---|---|
200 / 201 / 204 | Success. |
401 | Missing or invalid API key. |
404 | Unknown object, or record not in your business. |
422 | Blocked by a validation rule — see error in the body. |
500 | Server error. |
Errors return JSON: { "error": "message", "field": "optional_field" }. Lists cap at 500 records per request — paginate with limit & offset.
Code examples
JavaScript (fetch)
const API = "https://arvocrm.up.railway.app/api/v1";
const KEY = "ak_your_key_here";
// List leads
const res = await fetch(`${API}/leads`, {
headers: { Authorization: `Bearer ${KEY}` }
});
const { records } = await res.json();
// Create a lead
await fetch(`${API}/leads`, {
method: "POST",
headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ first_name: "Jane", email: "jane@example.com" })
});
Python (requests)
import requests
API = "https://arvocrm.up.railway.app/api/v1"
H = {"Authorization": "Bearer ak_your_key_here"}
# List deals
deals = requests.get(f"{API}/deals", headers=H).json()["records"]
# Create a contact
requests.post(f"{API}/contacts", headers=H, json={
"first_name": "Sam", "email": "sam@example.com"
})
Zapier / Make / n8n
Use a generic "Webhooks / HTTP" action: method POST, URL https://arvocrm.up.railway.app/api/v1/leads, header Authorization: Bearer ak_…, and a JSON body of the fields to set.