Skip to main content

CRM Public API: People, Companies, Deals, Tasks and Activities

H
Written by Hayko

CRM Public API: People, Companies, Deals, Tasks and Activities

The CRM Public API lets your own system read and change the CRM of your QrX organization: people, companies, deals, pipelines, tasks, the activity timeline and notes. This article is for developers. The base URL is https://api.qr-x.net. Every call needs Authorization: Bearer <accessToken>. For the access token, see "Developer Quickstart: QrX Public API and Webhooks".

What You Need

  • A QrX CRM plan that includes the public API. The public API is part of Business and Enterprise. Without it, a call whose key has the CRM scopes is refused with 402, and a key without the CRM scopes gets 403 CRM_SCOPE_MISSING first.

  • An API key (sales channel key) with the CRM scopes ticked, see "Create a Scoped API Key" below.

  • The tasks endpoints also need the Tasks feature, and the deals and pipelines endpoints need the Deals feature on your plan.

Create a Scoped API Key

CRM access is never granted by default. A key that has no restriction (Full access) has no CRM access. You must restrict the key and tick the CRM scopes yourself.

  1. Go to Settings > Business > Merchant Channels and open the sales channel whose key you want to use.

  2. Open the tab Settings. The block API access is under the API Key field. You need the permission Manage Channels to change it.

  3. Switch on Restrict this key.

  4. Under CRM, tick Read CRM people, companies, deals and pipelines (scope crm.read) and, if your system must write, Create and change CRM people, companies, deals and notes (scope crm.write).

  5. Click Save API access, check the list under Stops working and click Restrict the key. A change can take up to 30 seconds to apply.

Be careful: restricting a key also switches off every part that you do not tick, for integrations that work today. If this key also creates transactions, those keep working, but returns, inbound, stock, purchasing, fulfilment and tasks scopes must be ticked again if the key uses them. See "Restrict an API Key (API Access)".

Scopes

  • crm.read: all GET calls (pipelines, people, companies, deals, tasks, activities).

  • crm.write: all POST and PUT calls (create and change people, companies, deals, tasks and notes, move a deal, complete a task). A write scope does not include reading: tick both when you need both.

A scope that is missing answers 403 CRM_SCOPE_MISSING.

Get an Access Token

Send POST /api/v1/auth/token with the header QrX-MerchantChannel-API-Key set to your key. Use the access token from the answer as bearer token on every CRM call. Never send the API key itself to the CRM endpoints.

Endpoints

All paths start with /api/v1/crm.

  • Pipelines: GET /pipelines (pipelines with their stages: id, name, kind and probability).

  • People: GET /people, GET /people/{id}, POST /people, PUT /people/{id}.

  • Companies: GET /companies, GET /companies/{id}, POST /companies, PUT /companies/{id}.

  • Deals: GET /deals, GET /deals/{id}, POST /deals, PUT /deals/{id}, POST /deals/{id}/move.

  • Tasks: GET /tasks, GET /tasks/{id}, POST /tasks, PUT /tasks/{id}, POST /tasks/{id}/complete.

  • Activities: GET /activities?recordType=person&recordId={id}. recordType is person, company or deal.

  • Notes: POST /notes.

There is no delete call. Deleting, merging and erasing records is done in PortalX.

Reading Lists

Lists return items, nextCursor and hasMore. Pass nextCursor as cursor to get the next page and stop when hasMore is false. limit is 1 to 100 and defaults to 40.

  • People: most recently active first. q searches names, e-mail addresses and phone numbers. The list shows the primary e-mail and phone only; GET /people/{id} returns all contact points, tags and custom fields.

  • Companies: most recently active first. q searches names and domains.

  • Deals: most recently updated first. Filters: pipelineId, stageId, status (open, won or lost) and q.

  • Tasks: newest first. Filters: state (open or done), assigneeUserId, personId, companyId and dealId.

Creating and Changing Records

  • Idempotency-Key: every create call (POST for people, companies, deals, tasks and notes) needs the header Idempotency-Key with 8 to 80 characters: letters, digits and . _ : -. Send the same key again to retry and you get the first result back instead of a second record. Use a new key for each new record. Without a valid key the call answers 400 IDEMPOTENCY_KEY_REQUIRED.

  • version: every record carries a version. A PUT, a deal move and a task completion must send the version you read. If someone changed the record meanwhile, you get 409 CRM_CONFLICT: read the record again and retry with the new version.

  • Person: fields include firstName, lastName, jobTitle, companyId, lifecycleStageId, ownerUserId, language, country, emails, phones, tagIds and customFields. A person whose e-mail address or phone number already exists answers 409. Creating people counts toward the people limit of your plan.

  • Company: name, domains, vatNumber, chamberNumber, address fields, industry, sizeBand, website, ownerUserId, lifecycleStageId, tagIds and customFields.

  • Deal: title, pipelineId, stageId, value, currency, expectedCloseOn, probability, ownerUserId, primaryPersonId, personIds, companyId, source, tagIds and customFields. Without pipeline and stage the deal goes in the default pipeline. A PUT cannot change the stage: use POST /deals/{id}/move with toStageId, version and, for a lost stage, lostReasonId (and optionally lostNote) when the pipeline has lost reasons.

  • Note: POST /notes with recordType (person, company or deal), recordId and text. The text is plain text and is stored as a paragraph.

Tasks

Create a task with a title and an assigneeUserId of a user in your organization who can use the CRM. Without an assignee the call fails. Other fields: description, type, priority, dueAt, timeZoneId, reminderAt, recurrence, and the links personId, companyId and dealId. Completing a recurring task returns the finished task in task and the next one in next.

Activities and What Is Never Returned

The activity list shows the timeline of one record. Notes include their sanitized HTML. Calls, conversations, orders and returns appear as metadata only and are marked restricted. Private message content, payment details and call recording links are never in the API. The API also never returns merchant deals, order statistics, consent facts or lead score reasons.

Records you create through the API have no owner until you set ownerUserId.

Rate Limits

Reads (GET) are limited to 1200 requests per minute and writes (POST and PUT) to 300 requests per minute. When you go over, the API answers 429 with a Retry-After header. Wait that many seconds before you retry.

Errors

Errors use the same problem format as the rest of the Public API: code, detail and a requestId.

  • 400 IDEMPOTENCY_KEY_REQUIRED: the Idempotency-Key header is missing or has the wrong shape.

  • 401 UNAUTHORIZED: no valid access token.

  • 402: your plan does not include the public API or the feature, or CRM_PLAN_LIMIT_REACHED: a plan limit such as the number of people is reached. Upgrade the plan in PortalX.

  • 403 CRM_SCOPE_MISSING: the key does not have crm.read or crm.write. Tick the scope and wait 30 seconds.

  • 404 CRM_NOT_FOUND: the record does not exist in your organization.

  • 409 CRM_CONFLICT: the version is out of date (record_changed) or the person already exists (duplicate). Read the record again.

  • 422 VALIDATION_FAILED: a field is not valid, for example a missing version, an invalid cursor or a task without an assignee. The detail says which.

Webhook Events for CRM

QrX can also tell your system when something changes in the CRM. Create a webhook under Settings > Advanced > Webhooks (see "Webhooks and API Keys in PortalX") and tick the CRM events you want:

  • crm/person_created

  • crm/deal_created

  • crm/deal_moved

  • crm/deal_won

  • crm/deal_lost

  • crm/task_completed

  • crm/automation_triggered: sent by the automation action Send a webhook event.

CRM events go to every active webhook of your organization that ticked the event, whatever the sales channel. The payload only carries ids and business facts (for example personId, dealId, title, pipelineId, stageId, value, currency, ownerUserId), never e-mail addresses, phone numbers, notes or message text. Each event has an eventId that stays the same when QrX delivers it again, so drop an event whose eventId you already processed. Events older than 24 hours are not sent. A deal that is won or lost also sends crm/deal_moved. Deliveries are signed with X-QrX-Signature, see the webhook article.

Postman and OpenAPI

The QrX Public API Postman collection has the folders CRM Tasks and CRM Activities. The API documentation is at qrx.eu/api.

Common Problems

  • 403 on every CRM call. The key has full access or lacks the scope. Restrict the key and tick the CRM scopes.

  • 402 on every CRM call. Your plan does not include the CRM public API. It is part of Business and Enterprise.

  • 409 on update. Read the record again and send its current version.

  • Task creation refused. Check that assigneeUserId belongs to your organization and that the user can use the CRM.

  • Duplicate records after a retry. Reuse the same Idempotency-Key for a retry of the same record.

When to Contact Our Support Team

Contact QrX support at [email protected] when a ticked scope is still refused more than a minute after saving, or for production incidents. Include the request ID, the endpoint and the time, never your API key or access token.

Did this answer your question?