Skip to main content
The externalId field is the link between your record identifier and our customer record. Use it deliberately and create-or-update from your CRM becomes a single API call.

The rule

  • When a CRM event fires (created or updated), call POST /v1/customers with the same externalId every time.
  • We will create on first call, update on every subsequent call.
  • No bookkeeping needed on your side.

Why not just call PATCH?

PATCH requires our customer id (UUID) or your externalId in the path. If your CRM event fires before we know we have a record (race), or if you’re rebuilding state, you’d have to handle “not found → create”. POST with externalId handles both cases in one call.

Picking a good externalId

  • Stable. Use the immutable id from your CRM, not the email (emails change).
  • Scoped to your organisation. Two of your records cannot share an externalId. Reusing an id is the upsert signal — make sure you mean it.
  • Reasonable length. Up to 255 characters; usual CRM ids fit comfortably.
Good examples:
hubspot:123456789
salesforce:0035g000001a2BcQAA
internal:customer/7741
Bad examples:
jane@example.com    # changes when she changes email
1                   # collides easily across data sources

Worked example

CRM webhook fires with the contact:
{
  "contactId": "hubspot:123456789",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "phone": "+61400000000"
}
Send it to Instant Compliance:
curl -X POST https://app.instantcompliance.ai/api/v1/customers \
  -H "Authorization: Bearer ic_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hubspot-contact-123456789-2026-06-23T01:00:00Z" \
  -d '{
    "externalId": "hubspot:123456789",
    "fullName": "Jane Doe",
    "email": "jane@example.com",
    "phone": "+61400000000"
  }'
  • First call: returns 201 Created with our UUID.
  • Jane updates her phone in HubSpot → webhook re-fires → same call → returns 200 OK with the same UUID.

Email conflicts

If you try to send a record where email matches an existing customer with a different externalId, we reject with 409 conflict:
{
  "error": {
    "code": "conflict",
    "message": "A different customer record already uses this email address.",
    "details": {
      "conflicting_external_id": "salesforce:0035g000001a2BcQAA",
      "conflicting_id": "550e8400-e29b-41d4-a716-446655440000"
    }
  }
}
This usually means two of your data sources have separate ids for the same person. Resolve in your CRM (merge the contacts), then retry.