All CRM Lookup endpoints are workspace-scoped and require both the client and crm OAuth scopes. These endpoints are called by the CRM Middleware during PBX events (incoming calls, outgoing calls, chat sessions).

Headers: Authorization: Bearer {workspace-token}

The customer context is resolved automatically from the OAuth token.


GET /api/crm/lookup/contacts/search

Searches for contacts in the connected CRM by phone number or email address. Typically called during a screen-pop when a call rings on the PBX.

Query parameters

Parameter Type Required Description
phone string yes* Phone number to search for
email string yes* Email address to search for
display_name string no Caller display name — used by URL-builder integrations to construct the contact URL

*At least one of phone or email is required.

Response 200

{
  "contacts": [
    {
      "id": "crm-contact-uuid",
      "first_name": "Alice",
      "last_name": "Martin",
      "email": "alice.martin@acme.com",
      "phone_business_1": "+33142000000",
      "phone_mobile_1": "+33612345678",
      "company": "Acme Corp",
      "entity_url": "https://crm.example.com/contacts/123"
    }
  ]
}

If no match is found in the CRM, a dummy contact placeholder is returned so that 3CX can still trigger the call creation step.


POST /api/crm/lookup/contacts

Creates a new contact in the connected CRM.

Request body

Field Type Required Description
last_name string yes Last name
first_name string no First name
civility string no Civility / salutation
email string no Email address
phone string no Generic phone number
phone_business string no Business phone number
phone_mobile string no Mobile phone number
custom_value string no Custom CRM field value
call_direction string no Direction of the triggering call (inbound or outbound)

Response 201

{
  "response": "ok",
  "contact": { ... }
}

Response 400 — the CRM connector could not create the contact.


GET /api/crm/lookup/phone-calls

Returns the list of phone calls from the connected CRM connector.

Query parameters

Parameter Description
filter[direction] inbound, outbound, or internal
filter[status] Call status
filter[answered] Boolean — whether the call was answered
filter[number_from] Caller number
filter[number_to] Callee number
filter[number_did] DID / ring group number
filter[start_time] Call start time
filter[end_time] Call end time
filter[agent_email] Agent email address
filter[subject] Call subject
include Comma-separated relationships to sideload: segments, logs
sort Sort field: start_time, end_time, created_at, updated_at. Prefix with - for descending
per_page Results per page (default: 20)

Response 200 — paginated list of call objects.


POST /api/crm/lookup/phone-calls

Records a completed phone call in the connected CRM. This is the primary endpoint called by the CRM Middleware when a call ends on the PBX.

Request body

Field Type Required Description
direction string yes inbound, outbound, or internal (case-insensitive)
status string yes completed, failed, busy, no-answer, Missed, or Notanswered
number_from string yes* Caller number
number_to string yes* Callee number
number_external string yes** External party number
number_internal string yes** Internal extension number
source string no PBX source identifier (e.g. 3cx)
answered boolean no Whether the call was answered
duration string/integer no Call duration
start_time_utc string no Call start time in UTC — format: YYYY-MM-DDTHH:MM:SSZ
end_time_utc string no Call end time in UTC — format: YYYY-MM-DDTHH:MM:SSZ
subject string no Call subject
body string no Call notes or transcript excerpt
recording_url string no URL to the call recording
agent_first_name string no Answering agent's first name
agent_last_name string no Answering agent's last name
agent_email string no Answering agent's email address
queue_extension string no Queue or ring group extension

*number_from and number_to are mutually required — provide both or neither.
**number_external and number_internal are mutually required — provide both or neither.

Response 201

{
  "response": "success",
  "message": "Call saved successfully.",
  "call": { ... }
}

Response 400 — phone call logging is not enabled for this account.


POST /api/crm/lookup/phone-calls/context

Creates or updates a call context record during a live call. The context is used to pre-populate the CRM record so that when the call ends, the full entry can be enriched without relying solely on the final call payload.

Request body

Field Type Required Description
direction string yes inbound or outbound
number_from string yes (if inbound) Caller number
number_to string yes (if outbound) Callee number
source string no PBX source identifier (e.g. 3cx)
start_time_utc string no Call start time in UTC — format: YYYY-MM-DDTHH:MM:SSZ
start_time_reference string no Which timestamp to use as the context anchor: call (default) or segment
segment_dn_type string no DN type: extension, trunk, call_queue, voicemail, ivr, external_number, call_flow
context_data array no Arbitrary key-value pairs to store alongside the context

Response 201

{
  "response": "success",
  "message": "Call context saved successfully.",
  "call_context_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Token-based variant

For scenarios where the CRM Middleware cannot use a standard OAuth token, a pre-issued context token can be used instead:

POST /api/crm/phone-calls-context/{token}/{tokenSecret}

This endpoint accepts the same request body and requires no Authorization header. The token (UUID) and tokenSecret are issued by CX-Engine and scoped to a specific customer.


POST /api/crm/lookup/chats

Records a completed chat session in the connected CRM. Called by the CRM Middleware when a chat session ends on the PBX.

Request body

Field Type Required Description
email string yes Customer's email address
source string no PBX source identifier (e.g. 3cx)
number_external string no Customer's external number or identifier
name string no Customer's display name
start_time_utc string no Chat start time in UTC — format: YYYY-MM-DDTHH:MM:SSZ
end_time_utc string no Chat end time in UTC — format: YYYY-MM-DDTHH:MM:SSZ
duration string/integer no Chat duration
subject string no Chat subject
chat_messages string no Chat transcript or summary
queue_extension string no Queue or ring group extension
entity_type string no CRM entity type to link the chat to
entity_id string no CRM entity ID to link the chat to
agent string no Agent identifier
agent_first_name string no Answering agent's first name
agent_last_name string no Answering agent's last name
agent_email string no Answering agent's email address

Response 201

{
  "response": "success",
  "message": "Chat saved successfully.",
  "chat": { ... }
}

Response 400 — chat logging is not enabled for this account.