Browse documentation

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.

GET/api/v1/me

Inspect 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

FieldTypeRequiredDetails
workspace_iduuidNo
service_accountobjectNo
key_iduuidNo
permissionsDeveloperPermissionsNo
expires_atstringNoTimestamp
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/me' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
GET/api/v1/objects

Read 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[].

Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/objects' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
GET/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

ParameterTypeRequiredDetails
searchstringNoSearch Max 200 characters.
limitintegerNoDefault50 Min 1. Max 100.
cursorstringNoOpaque next cursor Max 500 characters.
statusstringNoStatus Max 80 characters.
listuuidNo
filterstringNoJSON Filter, mutually exclusive with list Max 10000 characters.

No request body is required.

Response

Use RecordPage.

Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/contacts' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
GET/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.

Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
POST/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

FieldTypeRequiredDetails
dataobjectYesObject field values. Only keys in the workspace object definition are allowed; required fields and field types are validated.

Response

Use Record.

Request shape (illustrative)
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"
  }
}'
PATCH/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

FieldTypeRequiredDetails
dataobjectYesObject field values. Only keys in the workspace object definition are allowed; required fields and field types are validated.
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.

Response

Use Record.

Request shape (illustrative)
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
}'
DELETE/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

FieldTypeRequiredDetails
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.

Response

Use OK.

Request shape (illustrative)
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
}'
GET/api/v1/{resource}/{id}/activities

Read 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

ParameterTypeRequiredDetails
cursoruuidNo

No request body is required.

Response

FieldTypeRequiredDetails
itemsobject[]No
next_cursorstring or nullNo
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001/activities' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
GET/api/v1/{resource}/{id}/stage-history

Read 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

ParameterTypeRequiredDetails
cursoruuidNo

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.

Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/contacts/00000000-0000-4000-8000-000000000001/stage-history' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
POST/api/v1/{resource}/{id}/activities

Add 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

FieldTypeRequiredDetails
bodystringYesNonblank note Max 10000 characters.

Response

object. Saved activity with service_account_id attribution

Request shape (illustrative)
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"
}'
GET/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

ParameterTypeRequiredDetails
searchstringNoSearch Max 200 characters.
limitintegerNoDefault50 Min 1. Max 100.
cursorstringNoOpaque next cursor Max 500 characters.
statusstringNoStatus Max 80 characters.
listuuidNo
filterstringNoJSON Filter, mutually exclusive with list Max 10000 characters.

No request body is required.

Response

Use RecordPage.

Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/records/people' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
GET/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.

Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
POST/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

FieldTypeRequiredDetails
dataobjectYesObject field values. Only keys in the workspace object definition are allowed; required fields and field types are validated.

Response

Use Record.

Request shape (illustrative)
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"
  }
}'
PATCH/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

FieldTypeRequiredDetails
dataobjectYesObject field values. Only keys in the workspace object definition are allowed; required fields and field types are validated.
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.

Response

Use Record.

Request shape (illustrative)
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
}'
DELETE/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

FieldTypeRequiredDetails
versionintegerYesPositive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1.

Response

Use OK.

Request shape (illustrative)
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
}'
GET/api/v1/records/{key}/{id}/activities

Read 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

ParameterTypeRequiredDetails
cursoruuidNo

No request body is required.

Response

FieldTypeRequiredDetails
itemsobject[]No
next_cursorstring or nullNo
Request shape (illustrative)
curl --request GET \
  --url 'https://app.drykraft.com/api/v1/records/people/00000000-0000-4000-8000-000000000001/activities' \
  --header 'Authorization: Bearer <YOUR_API_KEY>'
GET/api/v1/records/{key}/{id}/stage-history

Read 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

ParameterTypeRequiredDetails
cursoruuidNo

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.

Request shape (illustrative)
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>'
POST/api/v1/records/{key}/{id}/activities

Add 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

FieldTypeRequiredDetails
bodystringYesNonblank note Max 10000 characters.

Response

object. Saved activity with service_account_id attribution

Request shape (illustrative)
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"
}'