API

속성 일괄 생성

작성일 2026.04.23 | 수정일 2026.04.29

POST/crm-core/v1/properties/bulk

한 번의 요청으로 여러 개의 속성을 일괄 생성합니다. 각 속성은 개체(entityId) 단위로 저장되며 서로 다른 개체에 속한 속성을 섞어서 전달할 수도 있습니다. 배치 내부의 속성 name/key 중복, 기존 DB의 name 중복, 개체별 요금제 속성 한도(properties.maxPerEntity)가 모두 검증됩니다. OWNER 전용 권한이 필요합니다.

Body Params

NameTypeRequiredDescription
propertiesarray*생성할 속성 목록 (최소 1개, 최대 500개)
entityIdstring*속성이 속할 개체 ID
namestring*속성 이름 (동일 개체 내에서 고유)
fieldTypestring*속성 필드 유형 (TEXT, NUMBER, DATE, DROPDOWN 등)
descriptionstring속성 설명
propertyGroupIdstring속성이 속할 속성 그룹 ID
keystring속성 키 (영문 시작, 영문·숫자·언더스코어, 최대 63자)
isMaskedboolean개인정보 마스킹 여부 (기본 false)
optionsarrayDROPDOWN/RADIO/MULTI_CHECKBOX 유형에서 사용할 선택 옵션 목록
labelstring*옵션 표시 레이블
valuestring*옵션 저장 값
prioritynumber*옵션 정렬 우선순위

Response

NameTypeRequiredDescription
[]array*생성된 속성 객체 배열
propertyIdstring*생성된 속성 ID
accountIdstring*계정 고유 ID
workspaceIdstring워크스페이스 ID (워크스페이스에 속한 경우)
entityIdstring*속성이 속한 개체 ID
namestring*속성 이름
fieldTypestring*속성 필드 유형
descriptionstring속성 설명 (입력하지 않으면 응답에서 생략됨)
keystring | null속성 키 (지정한 경우)
propertyGroupIdstring | null속성 그룹 ID (지정한 경우)
createdBystring생성한 멤버 ID
dateCreateddate*생성 시각 (UTC)

Structure

코드 예제

const crypto = require('crypto');

const apiKey = 'NCSXXXXXXXXXXXXX';
const apiSecret = 'YOUR_API_SECRET';
const dateTime = new Date().toISOString();
const salt = crypto.randomBytes(16).toString('hex');
const signature = crypto.createHmac('sha256', apiSecret).update(dateTime + salt).digest('hex');
const authHeader = HMAC-SHA256 apiKey=${apiKey}, date=${dateTime}, salt=${salt}, signature=${signature};

const response = await fetch('https://api.solapi.com/crm-core/v1/properties/bulk', {
method: 'POST',
headers: { 'Authorization': authHeader, 'Content-Type': 'application/json' },
body: JSON.stringify({
"properties": [
{
"entityId": "CRMET1260423081530123XYZ11122233",
"name": "계약 금액",
"fieldType": "NUMBER",
"key": "contract_amount"
},
{
"entityId": "CRMET1260423081530123XYZ11122233",
"name": "담당자",
"fieldType": "TEXT"
}
]
})
});
const data = await response.json();

import hmac, hashlib, secrets, requests
from datetime import datetime, timezone

api_key = 'NCSXXXXXXXXXXXXX'
api_secret = 'YOUR_API_SECRET'
date_time = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
salt = secrets.token_hex(16)
signature = hmac.new(api_secret.encode(), (date_time + salt).encode(), hashlib.sha256).hexdigest()
auth_header = f'HMAC-SHA256 apiKey={api_key}, date={date_time}, salt={salt}, signature={signature}'

response = requests.post('https://api.solapi.com/crm-core/v1/properties/bulk', headers={
'Authorization': auth_header,
'Content-Type': 'application/json'
}, json={
"properties": [
{
"entityId": "CRMET1260423081530123XYZ11122233",
"name": "계약 금액",
"fieldType": "NUMBER",
"key": "contract_amount"
},
{
"entityId": "CRMET1260423081530123XYZ11122233",
"name": "담당자",
"fieldType": "TEXT"
}
]
})
data = response.json()

API_KEY="NCSXXXXXXXXXXXXX"
API_SECRET="YOUR_API_SECRET"
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
SALT=$(openssl rand -hex 16)
SIGNATURE=$(echo -n "${DATE}${SALT}" | openssl dgst -sha256 -hmac "${API_SECRET}" | awk '{print $NF}')
AUTH="HMAC-SHA256 apiKey=${API_KEY}, date=${DATE}, salt=${SALT}, signature=${SIGNATURE}"

curl -X POST 'https://api.solapi.com/crm-core/v1/properties/bulk' \
-H "Authorization: ${AUTH}" \
-H "Content-Type: application/json" \
-d '{"properties": [{"entityId": "CRMET1260423081530123XYZ11122233", "name": "계약 금액", "fieldType": "NUMBER", "key": "contract_amount"}, {"entityId": "CRMET1260423081530123XYZ11122233", "name": "담당자", "fieldType": "TEXT"}]}'

lightbulb

배치 내에서 동일한 개체·동일한 `name` 또는 동일한 개체·동일한 `key`를 가진 속성이 포함되어 있거나, 기존 DB에 동일 이름의 속성이 이미 존재하면 409 Conflict가 반환됩니다. 실패 시 어떤 속성도 생성되지 않습니다 (트랜잭션성 All-or-Nothing).

lightbulb

개체별 요금제 한도(`properties.maxPerEntity`)를 초과하면 403 Forbidden이 반환됩니다. 요청 실패 시 이미 증가된 사용량 카운터는 자동으로 롤백되므로 재시도해도 한도가 소진되지 않습니다.

lightbulb

**401 응답**: `{ "errorCode": "Unauthorized", "errorMessage": "권한이 없습니다." }`