CRM API
Use the API to read and write the data of one team from your own scripts. The API sends and takes JSON. The base address is https://crm.utilarium.app/api/v1.
There is also an OpenAPI 3.1 file for your tools.
Authentication
The owner of a team makes an API key in the CRM, in Settings under API keys. A team can have 5 keys. The CRM shows the secret one time. Keep it private. Each key works for one team only.
Send the secret in the Authorization header of each request. A secret is crm_ and 40 hex characters.
curl "https://crm.utilarium.app/api/v1/contacts?limit=10" \
-H "Authorization: Bearer $CRM_API_KEY"
Open the CRM to make a key.
Records and pages
Field names use camelCase. A list answers with data and nextCursor. A page has 50 records. Use limit to ask for up to 200. When nextCursor is not null, send it as cursor to get the next page. One record answers with data.
{ "data": [ { "id": "…", "firstName": "Ada" } ], "nextCursor": "1700000000000~abc" }
The q parameter searches. A text of 3 characters or more must be inside the record. A shorter text matches the start of the name. An amount is a whole number of cents: 120000 is 1,200.00. A time is in milliseconds since 1970.
Contacts
List contacts.
q: - Text inside the name, email, phone, title or tags. Under 3 characters: the start of the last name.
tag: - One tag.
companyId: - Contacts of one company.
owner: - An email address.
limit: - From 1 to 200. Default 50.
cursor: - The nextCursor of the last page.
curl "https://crm.utilarium.app/api/v1/contacts?limit=10" \
-H "Authorization: Bearer $CRM_API_KEY"
POST /contacts
Make one of contacts.
Body fields: firstName, lastName, email, phone, title, companyId, owner, tags.
curl -X POST "https://crm.utilarium.app/api/v1/contacts" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"firstName":"Ada","lastName":"Lovelace","email":"ada@example.com","tags":["customer"]}'
Read one of contacts.
curl "https://crm.utilarium.app/api/v1/contacts/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
Change one of contacts.
Body fields: firstName, lastName, email, phone, title, companyId, owner, tags.
curl -X PATCH "https://crm.utilarium.app/api/v1/contacts/ID" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phone":"+1 555 0100"}'
Delete one of contacts.
curl -X DELETE "https://crm.utilarium.app/api/v1/contacts/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
Companies
GET /companies
List companies.
q: - Text inside the name or domain. Under 3 characters: the start of the name.
owner: - An email address.
limit: - From 1 to 200. Default 50.
cursor: - The nextCursor of the last page.
curl "https://crm.utilarium.app/api/v1/companies?limit=10" \
-H "Authorization: Bearer $CRM_API_KEY"
POST /companies
Make one of companies.
Body fields: name, domain, phone, address, about, owner.
curl -X POST "https://crm.utilarium.app/api/v1/companies" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Analytical Engines","domain":"engines.example"}'
GET /companies/{id}
Read one of companies.
curl "https://crm.utilarium.app/api/v1/companies/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
PATCH /companies/{id}
Change one of companies.
Body fields: name, domain, phone, address, about, owner.
curl -X PATCH "https://crm.utilarium.app/api/v1/companies/ID" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phone":"+1 555 0101"}'
DELETE /companies/{id}
Delete one of companies.
curl -X DELETE "https://crm.utilarium.app/api/v1/companies/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
Deals
GET /deals
List deals.
q: - The start of the deal name.
stageId: - Deals of one stage, in board order.
contactId: - Deals of one contact.
companyId: - Deals of one company.
owner: - An email address.
limit: - From 1 to 200. Default 50.
cursor: - The nextCursor of the last page.
curl "https://crm.utilarium.app/api/v1/deals?limit=10" \
-H "Authorization: Bearer $CRM_API_KEY"
POST /deals
Make one of deals.
Body fields: name, amountCents, currency, stageId, contactId, companyId, owner, closeDate, position.
curl -X POST "https://crm.utilarium.app/api/v1/deals" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"First order","amountCents":120000,"currency":"USD"}'
GET /deals/{id}
Read one of deals.
curl "https://crm.utilarium.app/api/v1/deals/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
PATCH /deals/{id}
Change one of deals.
Body fields: name, amountCents, currency, stageId, contactId, companyId, owner, closeDate, position.
curl -X PATCH "https://crm.utilarium.app/api/v1/deals/ID" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stageId":"STAGE_ID"}'
DELETE /deals/{id}
Delete one of deals.
curl -X DELETE "https://crm.utilarium.app/api/v1/deals/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
Notes
GET /notes
List notes.
subjectKind (needed): - contact, company or deal.
subjectId (needed): - The id of the record.
limit: - From 1 to 200. Default 50.
cursor: - The nextCursor of the last page.
curl "https://crm.utilarium.app/api/v1/notes?subjectKind=contact&subjectId=CONTACT_ID" \
-H "Authorization: Bearer $CRM_API_KEY"
POST /notes
Make one of notes.
Body fields: subjectKind (needed), subjectId (needed), body (needed).
curl -X POST "https://crm.utilarium.app/api/v1/notes" \
-H "Authorization: Bearer $CRM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subjectKind":"contact","subjectId":"CONTACT_ID","body":"Called today."}'
GET /notes/{id}
Read one of notes.
curl "https://crm.utilarium.app/api/v1/notes/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
DELETE /notes/{id}
Delete one of notes.
curl -X DELETE "https://crm.utilarium.app/api/v1/notes/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
Pipeline stages
GET /stages
List the pipeline stages.
curl "https://crm.utilarium.app/api/v1/stages" \
-H "Authorization: Bearer $CRM_API_KEY"
GET /stages/{id}
Read one stage.
curl "https://crm.utilarium.app/api/v1/stages/ID" \
-H "Authorization: Bearer $CRM_API_KEY"
Errors
An error has a status and a JSON body. The body has a short code and a message to read.
{ "error": { "code": "unauthorized", "message": "The API key is not valid" } }
- 400
bad_request: The request has a wrong value. Read the message. - 401
unauthorized: The API key is missing or not valid. - 404
not_found: The record does not exist in the team of the key. - 409
conflict: The value is in use already, for example an email address. - 413
too_large: The body is too long. - 415
unsupported_media_type: Send the body as application/json. - 429
limit_reached: A limit is reached. Wait, or read the message.
Limits
- A key can make 120 requests each minute. Over that, the API answers 429.
- A team can make 20,000 changes each UTC day. The page and the API share this number.
- A body can have 1,000,000 characters.
- The record limits of the team apply to the API too. Read them on the start page.