CRM Syncs
Push graph8 records to a connected CRM. Five providers are supported:
| Provider | URL |
|---|---|
hubspot | hubspot.com |
salesforce | salesforce.com |
pipedrive | pipedrive.com |
zoho | zoho.com (CRM) |
sugarcrm | sugarcrm.com |
You must connect the CRM in Settings -> Integrations first - the {provider} path parameter resolves to the existing Nango connection for the org. If no connection exists you’ll get 404 Not Found.
| Endpoint | Method | Description |
|---|---|---|
/crm-syncs | GET | List configured CRM integrations |
/crm-syncs/{provider}/contacts/push | POST | Push contacts |
/crm-syncs/{provider}/companies/push | POST | Push companies |
/crm-syncs/{provider}/lists/push | POST | Modify list memberships (add/remove) |
/crm-syncs/{provider}/fields | GET | Discover available fields for an entity type |
/crm-syncs/{provider}/status | GET | Check connection health |
For machine-readable schemas see the interactive API docs.
List CRM Syncs
GET /crm-syncs
Returns connected CRM providers for the org. Disconnected providers are not returned.
Example
curl "https://be.graph8.com/api/v1/crm-syncs" \ -H "Authorization: Bearer $API_KEY"Response
{ "data": [ { "provider": "hubspot", "status": "connected", "connection_id": "nango-conn-abc123", "last_sync_at": null, "connected_at": null } ]}Push Contacts
POST /crm-syncs/{provider}/contacts/push
Bulk-create contacts on the CRM. The endpoint iterates each record and reports per-record errors in the response - one bad record does not fail the whole batch.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
records | object[] | Yes | Contact payloads in the CRM’s native field format (e.g. email, firstname, lastname for HubSpot) |
provider_fields | object | No | Optional field mapping overrides |
Example
curl -X POST "https://be.graph8.com/api/v1/crm-syncs/hubspot/contacts/push" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "records": [ {"email": "jane@acme.com", "firstname": "Jane", "lastname": "Smith"}, {"email": "bob@acme.com", "firstname": "Bob", "lastname": "Jones"} ] }'Response
{ "data": { "pushed_count": 2, "failed_count": 0, "errors": [] }}When a record fails, errors[] contains { "record": "<email>", "error": "<message>" }.
Errors
| Status | Meaning |
|---|---|
404 | No active {provider} connection. Connect in Integrations first |
Push Companies
POST /crm-syncs/{provider}/companies/push
Same shape as contact push. Each record is a company payload (e.g. name, domain, industry for HubSpot).
Example
curl -X POST "https://be.graph8.com/api/v1/crm-syncs/salesforce/companies/push" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "records": [ {"Name": "Acme Inc", "Website": "acme.com", "Industry": "Technology"} ] }'Push List Memberships
POST /crm-syncs/{provider}/lists/push
Add or remove contacts from CRM lists. Each records[] entry targets one list.
Request Body
Each item in records[] should look like:
| Field | Type | Description |
|---|---|---|
list_id | string | CRM list identifier |
add_contact_ids | string[] | CRM contact IDs to add |
remove_contact_ids | string[] | CRM contact IDs to remove |
Example
curl -X POST "https://be.graph8.com/api/v1/crm-syncs/hubspot/lists/push" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "records": [{ "list_id": "42", "add_contact_ids": ["101", "102"], "remove_contact_ids": ["999"] }] }'Response
{ "data": { "added": 2, "removed": 1, "errors": [] }}Discover Fields
GET /crm-syncs/{provider}/fields
Return the schema (custom + standard fields) for an entity type on the CRM. Useful before a push so you can validate field names dynamically.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
entity_type | string | contacts | One of contacts, companies, leads, deals |
Example
curl "https://be.graph8.com/api/v1/crm-syncs/hubspot/fields?entity_type=contacts" \ -H "Authorization: Bearer $API_KEY"Response
{ "data": { "fields": [ { "name": "First Name", "slug": "firstname", "type": "string", "required": false, "label": "First Name" } ] }}Errors
| Status | Meaning |
|---|---|
502 | The CRM rejected the discovery request - check message for the upstream error |
Get Status
GET /crm-syncs/{provider}/status
Health-check the connection by issuing a small read. Returns connected: false (with a message) if the connection is broken or the OAuth token expired - the endpoint never raises 5xx for connection failures.
Example
curl "https://be.graph8.com/api/v1/crm-syncs/hubspot/status" \ -H "Authorization: Bearer $API_KEY"Response
{ "data": { "provider": "hubspot", "connected": true, "connection_id": "nango-conn-abc123", "crm_type": "hubspot", "message": "Connection is healthy", "last_sync_at": null }}