News: Now offering a 90-day money-back guarantee!
Learn moreBadger Maps helps field sales teams plan routes and log visits against the accounts already sitting in their CRM. A native connector keeps those two systems in sync automatically — no CSV exports, no middleware, no manual re-entry. This page lays out exactly what a CRM vendor's API needs to support for our engineering team to build and maintain that connection.
Every requirement below is already met by the CRMs we connect to today, including HubSpot, Salesforce, Pipedrive, Zoho, Microsoft Dynamics, SAP, Sugar, monday.com, NetSuite, Veeva Vault, and Insightly. If a vendor's API looks similar to those, this should be a short evaluation.
Required — a hard blocker without it; we cannot build a native integration
Strongly preferred — a workaround is possible, but it adds cost and/or degrades the experience
Nice to have — improves the integration, but isn't blocking
Won't build against this — a hard no, regardless of workaround
Required — non-negotiable
Documented REST or GraphQL API
OAuth 2.0, connected per user
Users / team-member endpoint
Object and field metadata endpoints
Full CRUD, including delete
Last-modified filter + deletion tracking
Acceptable: Endpoint to request all the data using pagination.
Batch write endpoint
Documented, reasonable rate limits
Strongly preferred
API key issued per individual user (only if OAuth 2.0 isn't available)
Nice to have
Official SDKs or client libraries
Real-time webhooks for record changes
The foundation. If we can't reliably read the vendor's docs and hit their endpoints, nothing else on this list matters.
What we need | Why | Tier |
|---|---|---|
Public REST or GraphQL API | SOAP and one-off partner-only APIs add significant build and maintenance overhead. | Required |
Current, accurate developer documentation | We build and troubleshoot directly against the docs — outdated or partner-gated docs slow every stage of the build. | Required |
Official SDKs or client libraries | Not required — we call REST endpoints directly either way — but they speed up early prototyping. | Nice to have |
Each BadgerMaps user connects their own CRM login. We need a way to establish and refresh that connection per person, not per company.
What we need | Why | Tier |
|---|---|---|
OAuth 2.0 authorization code flow | The standard, lowest-friction path — a user clicks "Connect," authorizes, and we hold a scoped, refreshable token for that person. | Required |
Per-user credentials | A single shared, account-wide key with no way to identify which end user it belongs to can't support individual logins or permissions. | Required |
API key, issued per user | Viable if OAuth 2.0 isn't offered, but it means we build a dedicated key-entry page and manage refresh ourselves — more work on both sides. | Strongly preferred |
Username & password authentication | We don't ask users to hand us their CRM password, and won't build an integration that requires it. | Won't build against this |
Once a rep connects their account, we need to match them to the right person on the vendor's side.
What we need | Why | Tier |
|---|---|---|
Endpoint to list users / team members | Something like GET /users — lets us map a BadgerMaps rep to their CRM identity and respect record ownership. | Required |
Every account customizes its CRM differently. We need to discover that shape at runtime instead of guessing at it.
What we need | Why | Tier |
|---|---|---|
Objects list endpoint | Something like GET /objects — the set of entities available in the account (Contacts, Deals, Accounts, and any custom objects). | Required, unless there's no concept of custom objects |
Fields-per-object endpoint | Something like GET /objects/{name}/fields, returning: internal name, display label, field type, required flag, read-only flag, and the option list for any dropdown fields. | Required |
Impact if missing: we'd have to hand-maintain the vendor's field list ourselves. That locks customers into a fixed set of fields, breaks silently whenever the schema changes, and adds ongoing maintenance for both teams.
The core sync loop. All five operations need to exist for at least Contacts and one other core object.
What we need | Example | Tier |
|---|---|---|
Get record by ID | GET /objects/{name}/{id} | Required |
List / query records | GET /objects/{name}, with basic filtering | Required |
Create record | POST /objects/{name} | Required |
Update record | PATCH /objects/{name}/{id} | Required |
Delete record | DELETE /objects/{name}/{id} | Required |
Impact if delete is missing: a record removed inside BadgerMaps has no way to propagate back to the vendor's system — the two systems quietly drift out of sync.
We sync on a schedule, not by re-downloading every record every time. We need to ask "what changed since my last check?"
What we need | Why | Tier |
|---|---|---|
Filter records by last-modified time | Something like GET /objects/{name}?modified_since=… — the basis for every scheduled sync we run. | Required |
List records deleted in a time window | Without a way to ask "what got deleted between X and Y," removed CRM records keep quietly reappearing in BadgerMaps. | Required |
Real-time webhooks on record changes | Scheduled polling works fine — webhooks just let changes show up faster. | Nice to have |
For accounts with large record volumes, an initial sync or full re-sync has to move a lot of data quickly.
What we need | Why | Tier |
|---|---|---|
Native async bulk/export API | A job-based pattern — request a job, poll its status, download the result — built to move large datasets. | Required |
Impact if missing: the only fallback is paging through the standard records endpoint page by page, which is too slow for large accounts and can't reliably resume if interrupted partway through. Every CRM we currently support offers a native bulk path — a platform without one is an outlier.
When a rep updates many records at once from BadgerMaps, we need to send that as one call, not hundreds.
What we need | Why | Tier |
|---|---|---|
Batch write endpoint | Either an async job (submit, then poll for completion) or a synchronous batch request — either pattern works, as long as it updates many records in one call. | Required |
Impact if missing: mass updates fall back to one API call per record — slow, and the first thing to get rate-limited on a busy account.
A sync integration runs continuously in the background — we need to know how hard we're allowed to push it.
What we need | Why | Tier |
|---|---|---|
Published, predictable rate limits | So we can pace scheduled polling and bulk jobs without silently tripping throttling. | Required |
Limits reasonable for a sync workload | Periodic polling plus occasional bulk export/import needs headroom beyond a typical single-user session. | Required |
This is a first pass meant to give partner engineering teams a clear, self-serve checklist. If a vendor's platform meets the "Required" items above, a native integration is very likely feasible. If they're missing one or two, most gaps here have a known workaround worth discussing rather than an automatic disqualifier.
Badger Maps is a routing & mapping app that automates data collection and uplevels field team performance. From planning your day to managing your territories, Badger optimizes every aspect of the field sales process.
Looking for our logo?
Grab a Zip packed with our logo in PNG and EPS formats.