ARVO API Docs
Get an API key →

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 paramDescription
limitMax records to return (default 100, max 500).
offsetSkip 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

StatusMeaning
200 / 201 / 204Success.
401Missing or invalid API key.
404Unknown object, or record not in your business.
422Blocked by a validation rule — see error in the body.
500Server 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.