Sync existing customers
Import signups, trials and customers into Leads and exclude them from cold outreach.
Ask your agent to connect your customer list, or call this endpoint from your backend. Import existing records first, then send future signup and billing changes to the same endpoint. A generic inbound webhook that wakes the agent does not sync customer exclusions.
curl -X POST https://revnu.com/api/v1/customers \
-H "Authorization: Bearer $REVNU_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"source":"app","externalId":"cus_123","stage":"customer","email":"alex@example.com","website":"https://example.com","linkedinUrls":["https://www.linkedin.com/in/alex-example"]}'Body
Send one customer record per request. Required fields:
| Field | Value |
|---|---|
source |
Stable source label, 1–80 letters, digits, underscores or hyphens. |
externalId |
Stable record ID within that source, up to 200 characters. |
stage |
signed_up, trial, customer or former_customer. |
Supply at least one identifying field: email, website, domains or linkedinUrls. domains and linkedinUrls take at most 20 values each. Company domains exclude everyone at that company; personal providers such as gmail.com are rejected as company domains. An email at a personal provider excludes that address only. LinkedIn values must be personal profile URLs, not company pages.
Optional name and companyName describe the customer. Optional signedUpAt is a Unix timestamp in milliseconds. Supply sourceUpdatedAt with the source snapshot timestamp in milliseconds to prevent delayed imports or retries replacing newer relationship data. Keep using it on subsequent updates for the same source record. Text fields are limited to 320 characters, except for the source and ID limits above. Unknown fields are rejected. The API token determines the account; never include a creator ID.
Initial import with the CLI
Export your records as a JSON object containing a customers array, using the same fields as the request above. Each record needs a stable source and external ID. With a leads:write token configured in REVNU_API_TOKEN:
revnu customers import --json @customers.json --dry-run
revnu customers import --json @customers.jsonEach file can contain up to 5,000 records. The command retries transient errors and reports how many records completed before a failure. Correct the failure and rerun the same file; stable IDs make reimport safe. The dry run validates record shapes without writing. The server performs identifier validation when importing.
For one update:
revnu customers sync --json '{"source":"app","externalId":"cus_123","stage":"customer","email":"alex@example.com"}'Response
{ "ok": true, "leads": 1, "stage": "customer" }. A stale sourceUpdatedAt returns ignored: true and the retained relationship stage.
leads counts matched or created company records. A personal email or LinkedIn profile can return zero company records while still being excluded. Repeat the same source and externalId to update the relationship without duplicating the company. Outreach history is preserved. If several customer records match a company, a paying customer takes precedence over a trial, signup or former customer.
Known emails, company domains and LinkedIn profiles enter the enforced cold-outreach exclusions. Queued emails and open cold-outreach approval cards attached to matched leads or contacts are cancelled. Send gates recheck exclusions before sending; delivered messages cannot be recalled. Known contact profiles saved later are added to the exclusions too. An email alone cannot identify an unknown LinkedIn recipient.
Cancellation uses former_customer and keeps the exclusion. Omitting a customer from a later import does not unblock them. Customer-sync blocks cannot be removed through the blocklist endpoint.
A 400 identifies an invalid payload. A 401 means the token is missing or invalid; 403 means it lacks leads:write. Keep tokens server-side, verify signatures on your source provider's webhook handler, and retry network failures or 5xx responses with backoff. Read the current source record and serialize updates per customer ID so a delayed event cannot overwrite newer state. Check a synced identifier through the block list. Confirm a real source change appears there before treating ongoing sync as connected.
Frequently Asked Questions
No. Ask your agent when you want to connect your CRM, import a customer list or sync signups. A historical import protects the records imported so far; future changes need the ongoing connection too.