엔드포인트 별 인증 정책:
POST /metadata, POST /metadata/:id/status → x-api-key + X-CORPORATE-ID 필수 (기업 범위 내 문서만 조작)GET /metadata/:contractAddress/:tokenId → 공개 (헬스/메타데이터 서빙 용)/metadata메타데이터를 생성하고 MongoDB에 저장합니다.
자세한 스키마/타입별 예시는 docs/METADATA_AND_MINTING.md를 참고하세요.
| Name | Required | Value |
|---|---|---|
| x-api-key | Yes | 글로벌 API 키 |
| X-CORPORATE-ID | Yes | corporateAccounts 식별자 |
| Content-Type | Yes | application/json |
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
chainId |
string | ✅ | 사용 예정 체인 ID |
contractAddress |
string | ❌ | 매핑된 컨트랙트 주소 (배포 전이면 비워둠, 민팅 성공 시 자동 입력) |
tokenId |
string | ❌ | 매핑된 토큰 ID (민팅 성공 시 자동 입력) |
name |
string | ✅ | 메타데이터 이름 |
description |
string | ❌ | 설명 |
imageUrl |
url | ✅ | 이미지 경로 (S3/외부) |
externalUrl |
url | ❌ | 외부 상세 URL |
attributes |
array | ❌ | { traitType, value } 리스트 (Status 항목은 자동 관리) |
utility |
object | ✅ | 아래 상세 (type은 허용된 값만 사용) |
schemaVersion |
string | ❌ | JSON Schema 버전. 미지정 시 타입별 기본값 사용. 허용 값: opensea_flexible@1.0.0 (Flexible/자유), ticket_schema@1.0.0, coupon_schema@1.0.0, cert_schema@1.0.0 |
utility 구조:
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
type |
string | ✅ | Ticket, Coupon, Certificate, Flexible 등 (허용 타입만 사용) |
validationUrl |
url | ❌ | 검증 호출 URL |
data |
object | ✅ | 원본 데이터 ({ status: "Unused", ... } 등) ※ status 필드는 반드시 포함 |
docs/METADATA_AND_MINTING.md 참고)curl -X POST https://api.example.com/metadata \
-H "x-api-key: ${GLOBAL_SECRET_KEY}" \
-H "X-CORPORATE-ID: ${CORPORATE_ID}" \
-H "Content-Type: application/json" \
-d '{
"chainId": "43114",
"name": "Miji Ticket #1",
"imageUrl": "https://cdn.example.com/ticket.png",
"attributes": [
{ "traitType": "Seat", "value": "A-12" }
],
"utility": {
"type": "Ticket",
"data": { "status": "Unused", "validUntil": "2025-12-31T23:59:59Z" }
}
}'
생성된 Metadata 문서를 그대로 반환합니다. currentStatus는 utility.data.status 값이 복제되고, standardFields.attributes 내부에도 Status 항목이 자동 추가됩니다.
Certificate 타입의 경우 서버가 canonical JSON을 SHA-256으로 해시해 metadataHash를 계산하여 응답에 포함합니다(요청에 넣지 않아도 됨). 민팅 시 이 값을 그대로 사용하세요.
/metadata/:contractAddress/:tokenId오픈시 등 NFT 표준 JSON을 서빙합니다. 인증 없이 호출 가능합니다.
컨트랙트 배포 시 설정된 Base URI(https://.../metadata/<contractAddress>/ 또는 .../{id})가 이 엔드포인트를 가리키므로, 토큰의 tokenURI를 블록체인에서 조회하면 이 API로 연결됩니다.
{
"name": "Miji Ticket #1",
"description": "...",
"image": "https://cdn.example.com/ticket.png",
"external_url": "https://miji.app/tickets/1",
"attributes": [
{ "trait_type": "Seat", "value": "A-12" },
{ "trait_type": "Status", "value": "Unused" }
],
"utility": {
"type": "Ticket",
"data": { "status": "Unused", "...": "..." }
}
}
/metadata/:id/status메타데이터 상태를 동시에 두 곳(utility.data.status, standardFields.attributes)에 반영합니다.
curl -X POST https://api.example.com/metadata/6750121f7b3d9f1a6c4c4051/status \
-H "x-api-key: ${GLOBAL_SECRET_KEY}" \
-H "X-CORPORATE-ID: ${CORPORATE_ID}" \
-H "Content-Type: application/json" \
-d '{ "status": "Redeemed" }'
업데이트된 Metadata 문서가 반환됩니다. currentStatus, utility.data.status, Status trait가 모두 동일한 값으로 맞춰집니다.