업로드 API#

Snapkit의 업로드 API를 사용하여 프로그래밍 방식으로 이미지를 업로드하세요.

개요#

업로드 API는 HTTP POST 요청을 통해 이미지를 Snapkit에 업로드합니다. 인증된 요청은 API Key를 사용하여 조직의 저장소에 이미지를 저장합니다.

주요 특징:

  • Multipart/form-data 형식 지원
  • 한 번에 최대 100개 파일 업로드
  • 자동 이미지 메타데이터 추출
  • 태그 및 분류 지원

Upload#

이미지를 업로드합니다.

HTTP 요청#

POST https://api.snapkit.studio/organization/{organizationName}/images/{directoryId}

URL 파라미터#

파라미터

타입

설명

organizationName

string

필수. 조직 slug

directoryId

string

필수. 업로드할 디렉터리 ID

인증#

API Key를 사용하여 인증합니다:

X-API-Key: sk_live_myorg_1234567890abcdef

요청 파라미터#

파라미터

타입

필수

설명

files

File[]

필수

업로드할 이미지 파일들. 지원 포맷: JPEG, PNG, GIF, WebP, SVG, BMP, ICO, TIFF

tags

string[]

선택

이미지에 추가할 태그 배열

imageId

string

선택

커스텀 파일명. 미입력 시 원본 파일명 사용

요청 예제#

cURL:

curl -X POST "https://api.snapkit.studio/organization/acme-corp/images/dir-uuid" \
  -H "X-API-Key: sk_live_acme-corp_1234567890abcdef" \
  -F "files=@hero.jpg" \
  -F "files=@banner.png" \
  -F "tags=landing" \
  -F "tags=hero"

JavaScript (Fetch):

const formData = new FormData();
formData.append('files', file1);
formData.append('files', file2);
formData.append('tags', 'landing');
formData.append('tags', 'hero');
 
const response = await fetch(
  'https://api.snapkit.studio/organization/acme-corp/images/dir-uuid',
  {
    method: 'POST',
    headers: {
      'X-API-Key': 'sk_live_acme-corp_1234567890abcdef'
    },
    body: formData
  }
);
 
const assets = await response.json();

Python:

import requests
 
url = 'https://api.snapkit.studio/organization/acme-corp/images/dir-uuid'
headers = {'X-API-Key': 'sk_live_acme-corp_1234567890abcdef'}
files = [
    ('files', open('hero.jpg', 'rb')),
    ('files', open('banner.png', 'rb'))
]
data = {'tags': ['landing', 'hero']}
 
response = requests.post(url, headers=headers, files=files, data=data)
assets = response.json()

응답#

성공 (201 Created):

[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "filename": "hero.jpg",
    "url": "https://acme-corp-cdn.snapkit.studio/project/hero.jpg",
    "width": 1920,
    "height": 1080,
    "size": 245678,
    "format": "jpeg",
    "directoryId": "dir-uuid",
    "directoryPath": "/images/landing",
    "tags": [
      {
        "id": "tag-uuid-1",
        "name": "landing"
      },
      {
        "id": "tag-uuid-2",
        "name": "hero"
      }
    ],
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:00Z"
  }
]

응답 필드#

필드

타입

설명

id

string

Asset의 고유 ID

filename

string

파일명

url

string

CDN URL

width

number

이미지 너비 (픽셀)

height

number

이미지 높이 (픽셀)

size

number

파일 크기 (바이트)

format

string

이미지 포맷 (jpeg, png, webp 등)

directoryId

string

소속 디렉터리 ID

directoryPath

string

디렉터리 경로

tags

Tag[]

태그 배열

createdAt

string

생성 시간 (ISO 8601)

updatedAt

string

수정 시간 (ISO 8601)

인증#

API Key 생성#

  1. 웹 대시보드에서 Settings > API Keys로 이동
  2. Create API Key 버튼 클릭
  3. 키 이름 입력 및 권한 설정
  4. 생성된 키는 한 번만 표시되므로 즉시 안전한 곳에 저장

키 형식:

  • 테스트: sk_test_{organizationName}_{randomString}
  • 프로덕션: sk_live_{organizationName}_{randomString}

SDK 예제#

JavaScript/TypeScript#

설치:

npm install @repo/data-access

사용:

import { useImageControllerUploadImages } from '@repo/data-access/web';
 
function UploadComponent() {
  const uploadMutation = useImageControllerUploadImages();
 
  async function handleUpload(files: File[]) {
    const assets = await uploadMutation.mutateAsync({
      organizationName: 'acme-corp',
      directoryId: 'dir-uuid',
      data: {
        files,
        tags: ['landing', 'hero']
      }
    });
 
    console.log('Uploaded:', assets);
  }
 
  return (
    <input
      type="file"
      multiple
      onChange={(e) => handleUpload(Array.from(e.target.files || []))}
    />
  );
}

Node.js#

const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
 
async function uploadImages(filePaths, directoryId, apiKey) {
  const formData = new FormData();
 
  filePaths.forEach(filePath => {
    formData.append('files', fs.createReadStream(filePath));
  });
 
  formData.append('tags', 'landing');
 
  const response = await axios.post(
    `https://api.snapkit.studio/organization/acme-corp/images/${directoryId}`,
    formData,
    {
      headers: {
        'X-API-Key': apiKey,
        ...formData.getHeaders()
      }
    }
  );
 
  return response.data;
}

Python#

import requests
 
def upload_images(files, directory_id, api_key):
    url = f'https://api.snapkit.studio/organization/acme-corp/images/{directory_id}'
    headers = {'X-API-Key': api_key}
 
    files_data = [('files', open(f, 'rb')) for f in files]
    data = {'tags': ['landing', 'hero']}
 
    response = requests.post(url, headers=headers, files=files_data, data=data)
    return response.json()

제한사항#

파일 제한#

제한

최대 파일 크기

10MB

최대 파일 개수

100개/요청

지원 포맷

JPEG, PNG, GIF, WebP, SVG, BMP, ICO, TIFF

Rate Limiting#

API Key:

  • 기본 제한 없음
  • 키별 커스텀 Rate Limit 설정 가능

에러 처리#

에러 응답 형식#

{
  "statusCode": 401,
  "message": "Unauthorized access",
  "error": "Unauthorized"
}

에러 코드#

코드

설명

해결 방법

400

Bad Request

요청 파라미터 확인

401

Unauthorized

API Key 확인

403

Forbidden

API Key 권한 설정 확인

413

Payload Too Large

파일 크기를 10MB 이하로 줄이기

429

Too Many Requests

Rate Limit 대기 또는 설정 조정

507

Insufficient Storage

플랜 업그레이드 또는 기존 이미지 삭제

에러 처리 예제#

try {
  const response = await fetch(uploadUrl, {
    method: 'POST',
    headers: { 'X-API-Key': apiKey },
    body: formData
  });
 
  if (!response.ok) {
    const error = await response.json();
 
    switch (response.status) {
      case 401:
        console.error('인증 실패:', error.message);
        // 재로그인 또는 API Key 갱신
        break;
      case 413:
        console.error('파일 크기 초과:', error.message);
        // 파일 압축 또는 분할 업로드
        break;
      case 507:
        console.error('저장 용량 초과:', error.message);
        // 플랜 업그레이드 안내
        break;
      default:
        console.error('업로드 실패:', error.message);
    }
 
    throw new Error(error.message);
  }
 
  return await response.json();
} catch (error) {
  console.error('업로드 중 오류:', error);
  throw error;
}

보안#

API Key 보안#

권장사항:

  • 환경 변수에 API Key 저장
  • .gitignore에 환경 변수 파일 추가
  • 프로덕션/개발 환경 키 분리
  • 정기적인 키 교체
  • 최소 권한 원칙 적용

금지사항:

  • Git 저장소에 키 커밋 금지
  • 클라이언트 코드에 키 노출 금지
  • 공개 채널에서 키 공유 금지

HTTPS 필수#

모든 API 요청은 HTTPS를 통해 전송되어야 합니다:

// 올바른 사용
const url = 'https://api.snapkit.studio/...';
 
// 보안 위험 (사용 금지)
const url = 'http://api.snapkit.studio/...';

환경 변수 설정#

Node.js:

# .env
SNAPKIT_API_KEY=sk_live_acme-corp_1234567890abcdef
SNAPKIT_ORG_NAME=acme-corp
require('dotenv').config();
const apiKey = process.env.SNAPKIT_API_KEY;

Python:

# .env
SNAPKIT_API_KEY=sk_live_acme-corp_1234567890abcdef
import os
from dotenv import load_dotenv
 
load_dotenv()
api_key = os.getenv('SNAPKIT_API_KEY')

관련 문서#

지원#

문의사항이 있으시면 연락주세요: