API reference: CRM
Read companies, contacts, opportunities and their activity, and add notes, contacts, opportunities and to-dos. Never money.
Last updated
CRM endpoints need crm:read to read and crm:write to change. They never return an amount, recurring revenue, a margin or a contract value, and an opportunity is never closed won or lost here. Every sample reads the key from CURRENT_API_KEY and calls https://api.current.day/v1.
/v1/crm/companiesNeeds the crm:read scope. Pages with a cursor.
Lists the CRM companies this key can see, newest first, with type, owners, tags and contact details; with query, up to 25 best name matches and no further pages. It changes nothing and never shows money, contract values or cost. Pages with a cursor, at most 100 a page.
Parameters
Query parameters
- querytext, up to 200 charactersOptional
- Words in the company's name (at least 2 characters).
- customers_onlytrue or falseOptional
- Only companies marked as customers.
- limitinteger, 1 to 100Optional
- Rows per page, 1 to 100. 25 when left out.
- cursorcursorOptional
- next_cursor from the previous page.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/companies?customers_only=true&limit=10" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"name": {
"untrusted_text": "Lakeshore Dental",
"source": "customer"
},
"company_type": {
"untrusted_text": "Customer",
"source": "customer"
},
"classification": {
"untrusted_text": "Managed services",
"source": "customer"
},
"industry": {
"untrusted_text": "Dental",
"source": "customer"
},
"is_customer": true,
"is_active": true,
"website": {
"untrusted_text": "lakeshore-dental.example.test",
"source": "customer"
},
"phone": {
"untrusted_text": "(555) 010-4477",
"source": "customer"
},
"city": {
"untrusted_text": "Exampleton",
"source": "customer"
},
"state": null,
"country": {
"untrusted_text": "United States",
"source": "customer"
},
"owners": [
{
"id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48",
"name": {
"untrusted_text": "Priya Okafor",
"source": "customer"
},
"is_primary": true
}
],
"tags": [
{
"untrusted_text": "Dental",
"source": "customer"
},
{
"untrusted_text": "Managed",
"source": "customer"
}
],
"created_at": "2025-03-11T15:20:04.000Z",
"updated_at": "2026-10-29T09:41:17.000Z"
}
],
"next_cursor": "AQAGXyH39YhYgXbhAof0TceGFCDmEr9kQ2w7Ux1bZ3vLp0sDnF5aTcY",
"has_more": true
}/v1/crm/companies/{company_id}Needs the crm:read scope.
Reads one CRM company: its details, address, owners, tags and primary contact. It changes nothing and never shows money, contract values or cost.
Parameters
Path parameters
- company_iduuidRequired
- The company's id (read it with GET /v1/crm/companies or GET /v1/companies).
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/companies/c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"company": {
"id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"name": {
"untrusted_text": "Lakeshore Dental",
"source": "customer"
},
"company_type": {
"untrusted_text": "Customer",
"source": "customer"
},
"classification": {
"untrusted_text": "Managed services",
"source": "customer"
},
"industry": {
"untrusted_text": "Dental",
"source": "customer"
},
"is_customer": true,
"is_active": true,
"website": {
"untrusted_text": "lakeshore-dental.example.test",
"source": "customer"
},
"phone": {
"untrusted_text": "(555) 010-4477",
"source": "customer"
},
"city": {
"untrusted_text": "Exampleton",
"source": "customer"
},
"state": null,
"country": {
"untrusted_text": "United States",
"source": "customer"
},
"owners": [
{
"id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48",
"name": {
"untrusted_text": "Priya Okafor",
"source": "customer"
},
"is_primary": true
}
],
"tags": [
{
"untrusted_text": "Dental",
"source": "customer"
},
{
"untrusted_text": "Managed",
"source": "customer"
}
],
"created_at": "2025-03-11T15:20:04.000Z",
"updated_at": "2026-10-29T09:41:17.000Z",
"address_line1": {
"untrusted_text": "120 Harbor Lane",
"source": "customer"
},
"address_line2": {
"untrusted_text": "Suite 4",
"source": "customer"
},
"postal_code": "12345",
"primary_contact": {
"id": "d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85",
"name": {
"untrusted_text": "Dana Whitfield",
"source": "customer"
},
"title": {
"untrusted_text": "Office manager",
"source": "customer"
},
"email": {
"untrusted_text": "dana@lakeshore-dental.example.test",
"source": "customer"
},
"phone": {
"untrusted_text": "(555) 010-4477",
"source": "customer"
}
}
}
}
}/v1/crm/contactsNeeds the crm:read scope. Pages with a cursor.
Lists the CRM contacts this key can see, newest first, optionally for one company or matching words in the name, email or title. It changes nothing and never shows money. Pages with a cursor, at most 100 a page.
Parameters
Query parameters
- company_iduuidOptional
- Only this company's contacts.
- querytext, up to 200 charactersOptional
- Words in the name, email or title (at least 2 characters).
- active_onlytrue or falseOptional
- Leave out contacts marked inactive.
- limitinteger, 1 to 100Optional
- Rows per page, 1 to 100. 25 when left out.
- cursorcursorOptional
- next_cursor from the previous page.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/contacts?company_id=c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02&active_only=true" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85",
"name": {
"untrusted_text": "Dana Whitfield",
"source": "customer"
},
"first_name": {
"untrusted_text": "Dana",
"source": "customer"
},
"last_name": {
"untrusted_text": "Whitfield",
"source": "customer"
},
"title": {
"untrusted_text": "Office manager",
"source": "customer"
},
"email": {
"untrusted_text": "dana@lakeshore-dental.example.test",
"source": "customer"
},
"phone": {
"untrusted_text": "(555) 010-4477",
"source": "customer"
},
"mobile_phone": null,
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"company_name": {
"untrusted_text": "Lakeshore Dental",
"source": "customer"
},
"is_primary": true,
"active": true,
"created_at": "2025-03-11T15:24:52.000Z",
"updated_at": "2026-09-02T18:03:40.000Z"
}
],
"next_cursor": null,
"has_more": false
}/v1/crm/contactsNeeds the crm:write scope.
Adds a contact to a company: first and last name, and optionally email, title and phones. Current never emails the new contact or the customer; psa in the answer says whether the PSA's scheduled sync will create it there. Retry with the same request_id and it is never added twice.
Parameters
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- company_iduuidRequired
- The company's id (read it with GET /v1/crm/companies or GET /v1/companies).
- first_nametext, up to 100 charactersRequired
- last_nametext, up to 100 charactersRequired
- emailtext, up to 254 charactersOptional
- titletext, up to 200 charactersOptional
- phonetext, up to 50 charactersOptional
- mobile_phonetext, up to 50 charactersOptional
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X POST "https://api.current.day/v1/crm/contacts" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","company_id":"c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02","first_name":"Sam","last_name":"Rivera","email":"sam@lakeshore-dental.example.test","title":"Practice manager"}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"contact_id": "d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85",
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"psa": "next_sync"
}
}/v1/crm/contacts/{contact_id}Needs the crm:read scope.
Reads one CRM contact: name, title, email, phones, company and whether they are active. It changes nothing and never shows money.
Parameters
Path parameters
- contact_iduuidRequired
- The contact's id (read it with GET /v1/crm/contacts).
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/contacts/d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"contact": {
"id": "d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85",
"name": {
"untrusted_text": "Dana Whitfield",
"source": "customer"
},
"first_name": {
"untrusted_text": "Dana",
"source": "customer"
},
"last_name": {
"untrusted_text": "Whitfield",
"source": "customer"
},
"title": {
"untrusted_text": "Office manager",
"source": "customer"
},
"email": {
"untrusted_text": "dana@lakeshore-dental.example.test",
"source": "customer"
},
"phone": {
"untrusted_text": "(555) 010-4477",
"source": "customer"
},
"mobile_phone": null,
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"company_name": {
"untrusted_text": "Lakeshore Dental",
"source": "customer"
},
"is_primary": true,
"active": true,
"created_at": "2025-03-11T15:24:52.000Z",
"updated_at": "2026-09-02T18:03:40.000Z"
}
}
}/v1/crm/contacts/{contact_id}Needs the crm:write scope.
Changes a contact's name, title, email or phones (an empty text clears an optional field), never their company. Current never emails the contact or the customer; psa in the answer says whether the PSA's scheduled sync sends the change. Retry with the same request_id and it is applied once.
Parameters
Path parameters
- contact_iduuidRequired
- The contact's id (read it with GET /v1/crm/contacts).
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- first_nametext, up to 100 charactersOptional
- last_nametext, up to 100 charactersOptional
- emailtext, up to 254 charactersOptional
- titletext, up to 200 charactersOptional
- phonetext, up to 50 charactersOptional
- mobile_phonetext, up to 50 charactersOptional
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X PATCH "https://api.current.day/v1/crm/contacts/d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","title":"Practice director","phone":"(555) 010-4478"}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"contact_id": "d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85",
"psa": "next_sync"
}
}/v1/crm/dealsNeeds the crm:read scope. Pages with a cursor.
Lists the opportunities this key can see, newest first, optionally for one company or one status, with board, stage, owner, expected close and next step. It changes nothing and never shows an amount, MRR or margin. Pages with a cursor, at most 100 a page.
Parameters
Query parameters
- company_iduuidOptional
- Only this company's opportunities.
- statusone of the values listedOptional
openwonlost- limitinteger, 1 to 100Optional
- Rows per page, 1 to 100. 25 when left out.
- cursorcursorOptional
- next_cursor from the previous page.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/deals?status=open&limit=10" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09",
"name": {
"untrusted_text": "Lakeshore Dental: backup upgrade",
"source": "customer"
},
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"company_name": {
"untrusted_text": "Lakeshore Dental",
"source": "customer"
},
"board_id": "2c7f4a9e-6b31-4d85-b2e9-5a1d8c3f7b60",
"board_name": {
"untrusted_text": "New business",
"source": "staff"
},
"stage_id": "7a3d9e1b-5c28-4b46-9f0e-3c6a8d2b5e17",
"stage_name": {
"untrusted_text": "Proposal sent",
"source": "customer"
},
"status": "open",
"deal_type": {
"untrusted_text": "new_business",
"source": "customer"
},
"owner_id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48",
"owner_name": {
"untrusted_text": "Priya Okafor",
"source": "customer"
},
"expected_close": "2026-12-15",
"next_step": {
"untrusted_text": "Send the quote",
"source": "customer"
},
"closed_at": null,
"created_at": "2026-10-21T14:10:00.000Z",
"updated_at": "2026-11-03T16:45:09.000Z"
}
],
"next_cursor": null,
"has_more": false
}/v1/crm/dealsNeeds the crm:write scope.
Opens an opportunity on a company at an open stage of a board, with an optional expected close and next step; it never takes an amount and never closes as won or lost. Current never emails the customer; psa in the answer says whether the PSA's scheduled sync will create it there.
Parameters
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- company_iduuidRequired
- The company's id (read it with GET /v1/crm/companies or GET /v1/companies).
- nametext, up to 200 charactersRequired
- stage_iduuidRequired
- An open stage (not won, not lost); its board is the opportunity's board.
- expected_closetext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
- next_steptext, up to 500 charactersOptional
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X POST "https://api.current.day/v1/crm/deals" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","company_id":"c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02","name":"Lakeshore Dental: backup upgrade","stage_id":"7a3d9e1b-5c28-4b46-9f0e-3c6a8d2b5e17","expected_close":"2026-12-15","next_step":"Send the quote"}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"deal_id": "4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09",
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"psa": "next_sync"
}
}/v1/crm/deals/{deal_id}Needs the crm:read scope.
Reads one opportunity: its company, board, stage, status, owner, expected close and next step. It changes nothing and never shows an amount, MRR or margin.
Parameters
Path parameters
- deal_iduuidRequired
- The opportunity's id (read it with GET /v1/crm/deals).
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/deals/4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"deal": {
"id": "4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09",
"name": {
"untrusted_text": "Lakeshore Dental: backup upgrade",
"source": "customer"
},
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"company_name": {
"untrusted_text": "Lakeshore Dental",
"source": "customer"
},
"board_id": "2c7f4a9e-6b31-4d85-b2e9-5a1d8c3f7b60",
"board_name": {
"untrusted_text": "New business",
"source": "staff"
},
"stage_id": "7a3d9e1b-5c28-4b46-9f0e-3c6a8d2b5e17",
"stage_name": {
"untrusted_text": "Proposal sent",
"source": "customer"
},
"status": "open",
"deal_type": {
"untrusted_text": "new_business",
"source": "customer"
},
"owner_id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48",
"owner_name": {
"untrusted_text": "Priya Okafor",
"source": "customer"
},
"expected_close": "2026-12-15",
"next_step": {
"untrusted_text": "Send the quote",
"source": "customer"
},
"closed_at": null,
"created_at": "2026-10-21T14:10:00.000Z",
"updated_at": "2026-11-03T16:45:09.000Z"
}
}
}/v1/crm/deals/{deal_id}Needs the crm:write scope.
Changes an open opportunity's name, open stage on its board, expected close or next step, never its amount, owner or company and never to won or lost (a person closes it in Current). Current never emails the customer; psa in the answer says whether the PSA's scheduled sync sends the change.
Parameters
Path parameters
- deal_iduuidRequired
- The opportunity's id (read it with GET /v1/crm/deals).
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- nametext, up to 200 charactersOptional
- stage_iduuidOptional
- An open stage on the opportunity's own board.
- expected_stage_iduuidOptional
- The stage you last read: if it moved since, nothing changes and the answer is conflict.
- expected_closetext, up to 10 charactersOptional
- A date, YYYY-MM-DD.
- next_steptext, up to 500 charactersOptional
- An empty text clears it.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X PATCH "https://api.current.day/v1/crm/deals/4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","expected_close":"2027-01-15","next_step":"Book the walkthrough"}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"deal_id": "4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09",
"psa": "next_sync"
}
}/v1/crm/activitiesNeeds the crm:read scope. Pages with a cursor.
Lists the notes, calls and meetings on a company, a contact or an opportunity (name at least one), newest first. It changes nothing and never returns emails, formatting or money. Pages with a cursor, at most 100 a page.
Parameters
Query parameters
- company_iduuidOptional
- The company's activity.
- contact_iduuidOptional
- Only activity on this contact.
- deal_iduuidOptional
- Only activity on this opportunity.
- limitinteger, 1 to 100Optional
- Rows per page, 1 to 100. 25 when left out.
- cursorcursorOptional
- next_cursor from the previous page.
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
curl -sS --fail-with-body "https://api.current.day/v1/crm/activities?company_id=c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02&limit=10" \
-H "Authorization: Bearer $CURRENT_API_KEY"
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": [
{
"id": "a9c1f5e3-7b24-4d68-8e0a-6c2b9d4f1e57",
"kind": "call",
"title": {
"untrusted_text": "Quarterly check-in",
"source": "customer"
},
"body": {
"untrusted_text": "Talked through the backup upgrade. They would like a quote by Friday.",
"source": "customer"
},
"author_name": {
"untrusted_text": "Priya Okafor",
"source": "customer"
},
"occurred_at": "2026-11-05T15:30:00.000Z",
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"contact_id": "d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85",
"deal_id": "4e8b2c6a-9d13-4f70-a5c2-8b1e7d3f6a09"
}
],
"next_cursor": null,
"has_more": false
}/v1/crm/notesNeeds the crm:write scope.
Adds a note, call or meeting (plain text, up to 15,000 characters) to a company, and optionally one of its contacts or opportunities, as this key's holder. Current never emails the customer; psa in the answer says whether the PSA's scheduled sync will send it. Retry with the same request_id and it is never added twice.
Parameters
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- company_iduuidRequired
- The company's id (read it with GET /v1/crm/companies or GET /v1/companies).
- contact_iduuidOptional
- A contact of that company.
- deal_iduuidOptional
- An opportunity of that company.
- kindone of the values listedOptional
- note when left out.
notecallmeeting- titletext, up to 200 charactersOptional
- bodytext, up to 15,000 charactersRequired
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X POST "https://api.current.day/v1/crm/notes" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","company_id":"c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02","contact_id":"d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85","kind":"call","title":"Quarterly check-in","body":"Talked through the backup upgrade. They would like a quote by Friday."}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"note_id": "b3f8e1a6-7d24-4c09-a5e3-9f2c6d1b8a74",
"company_id": "c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02",
"kind": "call",
"psa": "next_sync"
}
}/v1/crm/todosNeeds the crm:write scope.
Adds a follow-up to-do for this key's holder or a named staff member, optionally on a company, contact or opportunity; it reaches their Microsoft To Do when they have connected it. Current never emails the customer about it.
Parameters
Header parameters
- Idempotency-KeyuuidOptional
- The same uuid as request_id, if you prefer a header. Send one or the other, or both with the same value.
Body parameters
- request_iduuidOptional
- A uuid you mint for this change. Send the same one again with the same key to retry safely: Current answers the first answer and never writes twice. Kept 24 hours per key; a retry with another key, a rotated one included, runs again. Required unless the Idempotency-Key header is sent.
- titletext, up to 200 charactersRequired
- notestext, up to 4,000 charactersOptional
- due_attext, up to 40 charactersOptional
- When it is due (ISO 8601, such as 2026-11-20T15:00:00Z).
- assignee_iduuidOptional
- A staff member of this workspace; the key's own holder when left out. A workspace key must name one.
- company_iduuidOptional
- The company's id (read it with GET /v1/crm/companies or GET /v1/companies).
- contact_iduuidOptional
- The contact's id (read it with GET /v1/crm/contacts).
- deal_iduuidOptional
- The opportunity's id (read it with GET /v1/crm/deals).
Errors
| Status | Code and meaning |
|---|---|
| 400 | bad_requestThe request was not in the expected shape. |
| 401 | unauthorizedThis token was not accepted. |
| 403 | not_allowed, frozen, module_offThis agent is not allowed to do that. This workspace is read only right now, so nothing can be changed. The API is not switched on for this workspace. |
| 404 | not_foundNothing was found with that id, or this agent cannot see it. |
| 405 | bad_request (method_not_allowed)That address does not accept this method. The Allow header lists the ones it does. |
| 409 | conflictSomeone changed this first. Read it again, then retry. |
| 413 | bad_request (body_too_large)The request body is larger than 64 KB. |
| 429 | rate_limited, send_cappedToo many requests from this token. Wait, then try again. This token has sent its limit of customer emails for now. Try again later. |
| 503 | degradedCurrent is busy. Try again in a minute. |
REQUEST_ID=$(uuidgen) # a new id for this change; send the same one again only to retry it
curl -sS --fail-with-body -X POST "https://api.current.day/v1/crm/todos" \
-H "Authorization: Bearer $CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{"request_id":"$REQUEST_ID","title":"Call Dana about the backup quote","due_at":"2026-11-20T15:00:00Z","company_id":"c2e9a0f4-1b7d-4c35-a8e6-5d3f7b1c9e02","contact_id":"d9c4a7e2-5f18-4b63-8e07-1a6c3f9d2b85"}
EOF
# A refusal exits non-zero and prints the error: read .error.code and .error.reason,
# for example with jq -r '.error.code, .error.reason'{
"data": {
"todo_id": "0d7a4c9f-2e58-4b36-91a7-5f3c8e6b2d40",
"assignee_id": "8d4b6f1a-2c9e-4e73-b05d-7a1e3c5f9b48"
}
}