Skip to content

Create an API key. The secret is returned once.

POST
/api/v1/workspaces/{workspaceId}/api-keys
curl --request POST \
--url https://api.crossmart.io/api/v1/workspaces/example/api-keys \
--header 'Content-Type: application/json' \
--data '{ "role": "OWNER", "customRoleId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "name": "Claude Desktop", "expiresAt": "2026-04-15T12:00:00Z" }'
workspaceId
required
string
Media typeapplication/json
object
role
required

At most your own access. CUSTOM needs customRoleId.

string
Allowed values: OWNER ADMIN EDITOR APPROVER VIEWER CUSTOM
customRoleId

One of the workspace’s roles, with CUSTOM

string format: uuid
name
required
string
<= 100 characters

Example

Claude Desktop
expiresAt

Leave empty for a key that does not expire

string format: date-time
Media typeapplication/json
object
apiKey
required
object
id
required
string format: uuid
name
required
string
role
required
string
Allowed values: OWNER ADMIN EDITOR APPROVER VIEWER CUSTOM
customRole
required

The workspace’s own role, when role is CUSTOM

object
id
required
string format: uuid
name
required
string
prefix
required

The first characters of the key, to tell keys apart

string
lastUsedAt
required
string format: date-time
nullable
expiresAt
required
string format: date-time
nullable
createdAt
required
string format: date-time
secret
required

The full key. Shown once; store it now.

string

Example

{
"apiKey": {
"role": "OWNER"
}
}

The organization’s plan does not allow this (ENTITLEMENTS_ENFORCED is on). code and feature say why; upgrading the plan resolves it.

Media typeapplication/json
object
statusCode
required
number
error
required
string
code
required
string
Allowed values: plan_limit_reached plan_feature_not_included
message
required
string
feature
required
string
Allowed values: active_listings channel_connections workspaces members api_keys ai_credits autonomous_agents bring_your_own_key
plan
required

The code of the organization’s plan

string
limit
required

Null is unlimited

number
nullable
usage
required
number
requested
required

How many more the request asked for

number

Example

{
"statusCode": 402,
"error": "Payment Required",
"code": "plan_limit_reached",
"message": "The Free plan includes 2 connected channels, and 2 are in use. Upgrade the plan to add more.",
"feature": "active_listings",
"plan": "free"
}