sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o123X-API-Key: sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6POST /api/v1/classes/{classId}/students/{studentCode}/points파라미터 | 타입 | 설명 | 예시 |
classId | string | 클래스 ID (그라운드에서 확인) | NP0hetJ3wyQKFtRnFeftmPiy8Dl7_2 |
studentCode | number | 학생 번호 (출석번호) | 2 |
헤더 | 값 | 필수 |
Content-Type | application/json | ✅ |
X-API-Key | 발급받은 API 키 | ✅ |
필드 | 타입 | 필수 | 설명 | 예시 |
type | string | ✅ | 포인트 종류 | "reward(+포인트)" 또는 "penalty(-포인트)" |
points | number | ✅ | 포인트 값 (0.01~1000) | 10.5 |
description | string | ✅ | 포인트 설명 (1~500자) | "퀴즈 정답" |
{
"type": "reward",
"points": 10,
"description": "타이핑 게임 클리어"
}
}{
"success": true,
"data": {
"recordId": "rec_xyz789",
"studentId": "stu_abc123",
"studentCode": 2,
"type": "reward",
"pointsAwarded": 10,
"bonusApplied": 0,
"totalPoints": 150.5,
"currentLevel": 5,
"leveledUp": false,
"createdAt": "2025-11-12T01:23:45.000Z"
},
"message": "포인트가 성공적으로 반영되었습니다."
}필드 | 타입 | 설명 |
recordId | string | 포인트 기록 ID |
studentId | string | 학생의 내부 ID |
studentCode | number | 학생 번호 |
type | string | 포인트 종류 |
pointsAwarded | number | 실제 부여된 포인트 |
bonusApplied | number | 적용된 보너스 배율 (0이면 보너스 없음) |
totalPoints | number | 부여 후 학생의 총 포인트 |
currentLevel | number | 학생의 현재 레벨 |
leveledUp | boolean | 레벨업 여부 |
createdAt | string | 포인트 부여 시각 (ISO 8601) |
{
"success": false,
"error": {
"code": "error_code",
"message": "에러 메시지",
"details": {}
}
}상태 코드 | 에러 코드 | 설명 | 해결 방법 |
400 | invalid_type | type이 올바르지 않음 | "reward" 또는 "penalty" 사용 |
400 | invalid_points | points 값이 범위를 벗어남 | 0.01~1000 사이 값 사용 |
400 | invalid_description | description이 비어있거나 너무 김 | 1~500자 사이 문자열 사용 |
400 | invalid_student_code | 학생 번호가 제공되지 않음 | studentCode 확인 |
401 | unauthorized | API 키가 없거나 유효하지 않음 | API 키 확인, X-API-Key 헤더 확인 |
403 | forbidden | 해당 클래스 접근 권한 없음 | classId 확인 |
404 | student_not_found | 학생을 찾을 수 없음 | studentCode 확인 |
429 | rate_limit_exceeded | 호출 제한 초과 | 잠시 후 재시도 |
500 | internal_error | 서버 내부 오류 | 잠시 후 재시도, 반복되면 문의 |
{
"success": false,
"error": {
"code": "student_not_found",
"message": "해당 학생 번호에 해당하는 학생을 찾을 수 없습니다.",
"details": {
"classId": "NP0hetJ3wyQKFtRnFeftmPiy8Dl3_2",
"studentCode": 99
}
}
}curl -X POST \
"https://growndcard.com/api/v1/classes/NP0hetJ3wyQKFtRnFeftmPiy8Dl2_2/students/2/points" \
-H "Content-Type: application/json" \
-H "X-API-Key: sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5123" \
-d '{
"type": "reward",
"points": 10,
"description": "퀴즈 정답"
}'const fetch = require('node-fetch');
const API_KEY = 'sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p2';
const BASE_URL = 'https://growndcard.com';
const CLASS_ID = 'NP0hetJ3wyQKFtRnFeftmPiy8Dl3_2';
async function awardPoints(studentCode, points, description) {
try {
const response = await fetch(
`${BASE_URL}/api/v1/classes/${CLASS_ID}/students/${studentCode}/points`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
},
body: JSON.stringify({
type: 'reward',
points: points,
description: description
})
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(`API Error: ${data.error.message}`);
}
console.log('포인트 부여 성공:', data.data);
return data.data;
} catch (error) {
console.error('포인트 부여 실패:', error.message);
throw error;
}
}
// 사용 예시
awardPoints(2, 10, '타이핑 게임 클리어')
.then(result => console.log('결과:', result))
.catch(error => console.error('에러:', error));import requests
import json
API_KEY = 'sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
BASE_URL = 'https://growndcard.com'
CLASS_ID = 'NP0hetJ3wyQKFtRnFeftmPiy8Dl2_2'
def award_points(student_code, points, description):
"""학생에게 포인트 부여"""
url = f'{BASE_URL}/api/v1/classes/{CLASS_ID}/students/{student_code}/points'
headers = {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
}
payload = {
'type': 'reward',
'points': points,
'description': description
}
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
data = response.json()
print(f"포인트 부여 성공: {data['data']}")
return data['data']
except requests.exceptions.HTTPError as e:
error_data = response.json()
print(f"API 에러: {error_data['error']['message']}")
raise
except Exception as e:
print(f"요청 실패: {str(e)}")
raise
# 사용 예시
if __name__ == '__main__':
result = award_points(2, 10, '퀴즈 정답')
print(f"총 포인트: {result['totalPoints']}")interface AwardPointsRequest {
type: 'reward' | 'penalty';
points: number;
description: string;
source?: string;
metadata?: Record<string, any>;
}
interface AwardPointsResponse {
success: boolean;
data?: {
recordId: string;
studentCode: number;
pointsAwarded: number;
totalPoints: number;
currentLevel: number;
leveledUp: boolean;
createdAt: string;
};
message?: string;
}
class GroundApiClient {
private apiKey: string;
private baseUrl: string;
private classId: string;
constructor(apiKey: string, classId: string) {
this.apiKey = apiKey;
this.classId = classId;
this.baseUrl = 'https://growndcard.com';
}
async awardPoints(
studentCode: number,
request: AwardPointsRequest
): Promise<AwardPointsResponse> {
const url = `${this.baseUrl}/api/v1/classes/${this.classId}/students/${studentCode}/points`;
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey
},
body: JSON.stringify(request)
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error?.message || 'API 호출 실패');
}
return data;
}
}
// 사용 예시
const client = new GroundApiClient(
'sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p3',
'NP0hetJ3wyQKFtRnFeftmPiy8Dl3_2'
);
async function example() {
try {
const result = await client.awardPoints(2, {
type: 'reward',
points: 10,
description: '타이핑 게임 클리어'
});
console.log('포인트 부여 성공:', result.data);
} catch (error) {
console.error('포인트 부여 실패:', error);
}
}<?php
function awardPoints($studentCode, $points, $description) {
$apiKey = 'sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p1';
$classId = 'NP0hetJ3wyQKFtRnFeftmPiy8Dl3_2';
$baseUrl = 'https://growndcard.com';
$url = "{$baseUrl}/api/v1/classes/{$classId}/students/{$studentCode}/points";
$data = [
'type' => 'reward',
'points' => $points,
'description' => $description
];
$options = [
'http' => [
'method' => 'POST',
'header' => [
'Content-Type: application/json',
"X-API-Key: {$apiKey}"
],
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
if ($response === false) {
throw new Exception('API 호출 실패');
}
$result = json_decode($response, true);
if (!$result['success']) {
throw new Exception($result['error']['message']);
}
return $result['data'];
}
// 사용 예시
try {
$result = awardPoints(2, 10, '퀴즈 정답');
echo "포인트 부여 성공: 총 포인트 = {$result['totalPoints']}\n";
} catch (Exception $e) {
echo "에러: " . $e->getMessage() . "\n";
}