Versioned CRM API
Current release · Updated October 2, 2026
DryKraft Versioned CRM API reference: methods, permissions, request fields, response shapes, examples and current limits. Read authentication and error handling first.
/api/v1/meInspect API identity
Access: Scoped API key · Success: 200
Bearer key only; a browser cookie is not accepted. Identity is fixed to one workspace; another host/X-Workspace-ID cannot switch it. Returns effective permissions and expiry.
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
workspace_id | uuid | No | |
service_account | object | No | |
key_id | uuid | No | |
permissions | DeveloperPermissions | No | |
expires_at | string | No | Timestamp |
curl --request GET \
--url 'https://app.drykraft.com/api/v1/me' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/objectsRead authorized schemas
Access: Scoped API key · Success: 200
Returns only object definitions within this key’s effective Read grants, including current typed fields. New objects receive no automatic grant.
No request body is required.
Response
Object[].
curl --request GET \
--url 'https://app.drykraft.com/api/v1/objects' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/{resource}List records by CRM collection
Access: Scoped API key · Success: 200
Read permission required. Resource aliases: contacts=people, companies, leads, opportunities=deals and tasks. Use records/key for custom or financial read access. Same validated search/status/filter/smart-list/cursor contract as the application; archives are excluded.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
search | string | No | Search Max 200 characters. |
limit | integer | No | Default50 Min 1. Max 100. |
cursor | string | No | Opaque next cursor Max 500 characters. |
status | string | No | Status Max 80 characters. |
list | uuid | No | |
filter | string | No | JSON Filter, mutually exclusive with list Max 10000 characters. |
No request body is required.
Response
Use RecordPage.
curl --request GET \
--url 'https://app.drykraft.com/api/v1/contacts' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/{resource}/{id}Read record by CRM collection
Access: Scoped API key · Success: 200
Object Read grant required. IDs from another workspace are unavailable. Archived contact IDs resolve to the remaining canonical ID.
No request body is required.
Response
Use Record.
curl --request GET \
--url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/{resource}Create record by CRM collection
Access: Scoped API key · Success: 201
Create plus Read grants required. Mandatory UUID Idempotency-Key; identical retries return the original result without repeated mutation/events. Shared CRM schema/currency/relation validation applies. Financial creation is prohibited; API business writes require active billing access.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
data | object | Yes | Object field values. Only keys in the workspace object definition are allowed; required fields and field types are validated. |
Response
Use Record.
curl --request POST \
--url 'https://app.drykraft.com/api/v1/contacts' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"data": {
"name": "Example person"
}
}'/api/v1/{resource}/{id}Patch record by CRM collection
Access: Scoped API key · Success: 200
Update plus Read grants and latest version required. Omitted fields remain unchanged. Mandatory UUID Idempotency-Key; changed input/path with that UUID conflicts. Archived sources cannot be edited. Financial writes are prohibited.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
data | object | Yes | Object field values. Only keys in the workspace object definition are allowed; required fields and field types are validated. |
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
Response
Use Record.
curl --request PATCH \
--url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"data": {
"name": "Example person"
},
"version": 1
}'/api/v1/{resource}/{id}Delete record by CRM collection
Access: Scoped API key · Success: 200
Delete plus Read grants, current version and mandatory UUID Idempotency-Key required. Shared relation/merge-history safeguards apply. Financial deletion is prohibited. No restore endpoint.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
Response
Use OK.
curl --request DELETE \
--url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"version": 1
}'/api/v1/{resource}/{id}/activitiesRead activity by CRM collection
Access: Scoped API key · Success: 200
Read grant required. Canonical record activity,25 rows per cursor page. Scope is the path object; another object cannot be used to inspect this record.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
cursor | uuid | No |
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
items | object[] | No | |
next_cursor | string or null | No |
curl --request GET \
--url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001/activities' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/{resource}/{id}/stage-historyRead deal stage history by CRM collection
Access: Scoped API key · Success: 200
Deals Read grant required. key must be deals or resource must be opportunities. Other objects return404. Same25-row version-ordered cursor and saved-name snapshots as the application.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
cursor | uuid | No |
No request body is required.
Response
Use DealStageHistory. Newest record-version first,25 transitions per page. Snapshots preserve stage/pipeline names; no pre-release backfill. Removed with the deal.
curl --request GET \
--url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001/stage-history' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/{resource}/{id}/activitiesAdd note by CRM collection
Access: Scoped API key · Success: 201
Note plus Read grants and mandatory UUID Idempotency-Key required. Adds an internal note through the shared activity mutation/event path; does not send a message. Archived contact references resolve to the remaining contact.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
body | string | Yes | Nonblank note Max 10000 characters. |
Response
object. Saved activity with service_account_id attribution
curl --request POST \
--url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001/activities' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"body": "Example internal note"
}'/api/v1/records/{key}List records by object key
Access: Scoped API key · Success: 200
Read permission required. Resource aliases: contacts=people, companies, leads, opportunities=deals and tasks. Use records/key for custom or financial read access. Same validated search/status/filter/smart-list/cursor contract as the application; archives are excluded.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
search | string | No | Search Max 200 characters. |
limit | integer | No | Default50 Min 1. Max 100. |
cursor | string | No | Opaque next cursor Max 500 characters. |
status | string | No | Status Max 80 characters. |
list | uuid | No | |
filter | string | No | JSON Filter, mutually exclusive with list Max 10000 characters. |
No request body is required.
Response
Use RecordPage.
curl --request GET \
--url 'https://app.drykraft.com/api/v1/records/people' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/records/{key}/{id}Read record by object key
Access: Scoped API key · Success: 200
Object Read grant required. IDs from another workspace are unavailable. Archived contact IDs resolve to the remaining canonical ID.
No request body is required.
Response
Use Record.
curl --request GET \
--url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/records/{key}Create record by object key
Access: Scoped API key · Success: 201
Create plus Read grants required. Mandatory UUID Idempotency-Key; identical retries return the original result without repeated mutation/events. Shared CRM schema/currency/relation validation applies. Financial creation is prohibited; API business writes require active billing access.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
data | object | Yes | Object field values. Only keys in the workspace object definition are allowed; required fields and field types are validated. |
Response
Use Record.
curl --request POST \
--url 'https://app.drykraft.com/api/v1/records/people' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"data": {
"name": "Example person"
}
}'/api/v1/records/{key}/{id}Patch record by object key
Access: Scoped API key · Success: 200
Update plus Read grants and latest version required. Omitted fields remain unchanged. Mandatory UUID Idempotency-Key; changed input/path with that UUID conflicts. Archived sources cannot be edited. Financial writes are prohibited.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
data | object | Yes | Object field values. Only keys in the workspace object definition are allowed; required fields and field types are validated. |
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
Response
Use Record.
curl --request PATCH \
--url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"data": {
"name": "Example person"
},
"version": 1
}'/api/v1/records/{key}/{id}Delete record by object key
Access: Scoped API key · Success: 200
Delete plus Read grants, current version and mandatory UUID Idempotency-Key required. Shared relation/merge-history safeguards apply. Financial deletion is prohibited. No restore endpoint.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
Response
Use OK.
curl --request DELETE \
--url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"version": 1
}'/api/v1/records/{key}/{id}/activitiesRead activity by object key
Access: Scoped API key · Success: 200
Read grant required. Canonical record activity,25 rows per cursor page. Scope is the path object; another object cannot be used to inspect this record.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
cursor | uuid | No |
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
items | object[] | No | |
next_cursor | string or null | No |
curl --request GET \
--url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001/activities' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/records/{key}/{id}/stage-historyRead deal stage history by object key
Access: Scoped API key · Success: 200
Deals Read grant required. key must be deals or resource must be opportunities. Other objects return404. Same25-row version-ordered cursor and saved-name snapshots as the application.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
cursor | uuid | No |
No request body is required.
Response
Use DealStageHistory. Newest record-version first,25 transitions per page. Snapshots preserve stage/pipeline names; no pre-release backfill. Removed with the deal.
curl --request GET \
--url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001/stage-history' \
--header 'Authorization: Bearer <YOUR_API_KEY>'/api/v1/records/{key}/{id}/activitiesAdd note by object key
Access: Scoped API key · Success: 201
Note plus Read grants and mandatory UUID Idempotency-Key required. Adds an internal note through the shared activity mutation/event path; does not send a message. Archived contact references resolve to the remaining contact.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
body | string | Yes | Nonblank note Max 10000 characters. |
Response
object. Saved activity with service_account_id attribution
curl --request POST \
--url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001/activities' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Idempotency-Key: <REQUEST_UUID>' \
--header 'Content-Type: application/json' \
--data '{
"body": "Example internal note"
}'