빠른 시작 가이드

몇 분 안에 Walla Open API 시작하기

빠른 시작 가이드

이 가이드에서는 Walla Open API의 인증, 폼 조회, 응답 조회까지 기본 흐름을 빠르게 살펴봅니다.

사전 준비사항

시작하기 전에 아래 항목을 확인하세요.

  • 워크스페이스 접근 권한이 있는 Walla 계정
  • API 키 (Walla 워크스페이스 설정에서 발급)
  • 워크스페이스에 게시된 폼 1개 이상

1단계: 환경 설정

먼저 API 키를 환경 변수로 안전하게 저장합니다.

옵션 A: .env 파일 사용

프로젝트 루트에 .env 파일을 만드세요.

WALLA_API_KEY=your_api_key_here

중요: API 키가 커밋되지 않도록 .env 파일을 .gitignore에 추가하세요.

옵션 B: 셸에서 내보내기

export WALLA_API_KEY=your_api_key_here

2단계: 첫 API 호출하기

API 키가 정상 동작하는지 워크스페이스 조회로 확인해 봅니다.

cURL 사용

curl -X GET "https://api.walla.my/open-api/v1/workspaces" \
  -H "X-WALLA-API-KEY: $WALLA_API_KEY" \
  -H "Content-Type: application/json"

JavaScript/TypeScript 사용

// dotenv를 설치해야 합니다: npm install dotenv
require('dotenv').config();

const API_KEY = process.env.WALLA_API_KEY;
const BASE_URL = 'https://api.walla.my/open-api/v1';

async function getWorkspaces() {
  const response = await fetch(`${BASE_URL}/workspaces`, {
    method: 'GET',
    headers: {
      'X-WALLA-API-KEY': API_KEY,
      'Content-Type': 'application/json'
    }
  });

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }

  const data = await response.json();
  return data.data;
}

// 실행
getWorkspaces()
  .then(workspaces => {
    console.log('Your workspaces:');
    workspaces.forEach(ws => {
      console.log(`- ${ws.name} (ID: ${ws.id})`);
    });
  })
  .catch(error => console.error('Error:', error));

Python 사용

# requests 설치: pip install requests python-dotenv
import os
import requests
from dotenv import load_dotenv

load_dotenv()

API_KEY = os.getenv('WALLA_API_KEY')
BASE_URL = 'https://api.walla.my/open-api/v1'

def get_workspaces():
    headers = {
        'X-WALLA-API-KEY': API_KEY,
        'Content-Type': 'application/json'
    }

    response = requests.get(f'{BASE_URL}/workspaces', headers=headers)
    response.raise_for_status()
    return response.json()['data']

# 실행
if __name__ == '__main__':
    workspaces = get_workspaces()
    print('Your workspaces:')
    for ws in workspaces:
        print(f"- {ws['name']} (ID: {ws['id']})")

예상 출력:

Your workspaces:
- Marketing Team (ID: workspace_123)
- Customer Success (ID: workspace_456)

3단계: 폼 목록 조회하기

전체 폼 목록을 조회해 봅니다.

JavaScript

async function getAllForms() {
  const response = await fetch(`${BASE_URL}/forms`, {
    method: 'GET',
    headers: {
      'X-WALLA-API-KEY': API_KEY,
      'Content-Type': 'application/json'
    }
  });

  const data = await response.json();
  return data.data;
}

getAllForms()
  .then(workspaces => {
    workspaces.forEach(workspace => {
      console.log(`\nWorkspace: ${workspace.workspaceName}`);
      workspace.forms.forEach(formWrapper => {
        const form = formWrapper.form;
        console.log(`  - ${form.title} (ID: ${form.id})`);
        console.log(`    Submissions: ${formWrapper.analytics.submissions}`);
      });
    });
  })
  .catch(error => console.error('Error:', error));

Python

def get_all_forms():
    headers = {
        'X-WALLA-API-KEY': API_KEY,
        'Content-Type': 'application/json'
    }

    response = requests.get(f'{BASE_URL}/forms', headers=headers)
    response.raise_for_status()
    return response.json()['data']

# 실행
workspaces = get_all_forms()
for workspace in workspaces:
    print(f"\nWorkspace: {workspace['workspaceName']}")
    for form_wrapper in workspace['forms']:
        form = form_wrapper['form']
        print(f"  - {form['title']} (ID: {form['id']})")
        print(f"    Submissions: {form_wrapper['analytics']['submissions']}")

4단계: 폼 응답 조회하기

특정 폼의 응답 데이터를 가져옵니다.

JavaScript

async function getResponses(formId, page = 1, limit = 20) {
  const url = new URL(`${BASE_URL}/forms/${formId}/responses`);
  url.searchParams.set('page', page);
  url.searchParams.set('limit', limit);

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'X-WALLA-API-KEY': API_KEY,
      'Content-Type': 'application/json'
    }
  });

  const data = await response.json();
  return data.data;
}

// 응답 조회
getResponses('form_abc', 1, 10)
  .then(data => {
    console.log(`\nTotal responses: ${data.pagination.totalCount}`);
    console.log(`Page ${data.pagination.page} of ${data.pagination.totalPages}\n`);

    data.responses.forEach((response, index) => {
      console.log(`Response ${index + 1}:`);
      console.log(`  ID: ${response.responseId}`);
      console.log(`  Customer: ${response.customerKey || 'Anonymous'}`);
      console.log(`  Submitted: ${response.submittedAt}`);
    });
  })
  .catch(error => console.error('Error:', error));

Python

def get_responses(form_id, page=1, limit=20):
    headers = {
        'X-WALLA-API-KEY': API_KEY,
        'Content-Type': 'application/json'
    }

    response = requests.get(
        f'{BASE_URL}/forms/{form_id}/responses',
        headers=headers,
        params={'page': page, 'limit': limit}
    )
    response.raise_for_status()
    return response.json()['data']

# 응답 조회
data = get_responses('form_abc', page=1, limit=10)

print(f"\nTotal responses: {data['pagination']['totalCount']}")
print(f"Page {data['pagination']['page']} of {data['pagination']['totalPages']}\n")

for i, response in enumerate(data['responses'], 1):
    print(f"Response {i}:")
    print(f"  ID: {response['responseId']}")
    print(f"  Customer: {response.get('customerKey', 'Anonymous')}")
    print(f"  Submitted: {response['submittedAt']}")

전체 워크플로 예제

위 단계를 하나로 합친 예제입니다.

JavaScript

require('dotenv').config();

const API_KEY = process.env.WALLA_API_KEY;
const BASE_URL = 'https://api.walla.my/open-api/v1';

class WallaAPI {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.headers = {
      'X-WALLA-API-KEY': apiKey,
      'Content-Type': 'application/json'
    };
  }

  async request(endpoint, options = {}) {
    const url = `${BASE_URL}${endpoint}`;
    const response = await fetch(url, {
      ...options,
      headers: { ...this.headers, ...options.headers }
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error);
    }

    return await response.json();
  }

  async getWorkspaces() {
    const data = await this.request('/workspaces');
    return data.data;
  }

  async getForms() {
    const data = await this.request('/forms');
    return data.data;
  }

  async getResponses(formId, page = 1, limit = 20) {
    const data = await this.request(
      `/forms/${formId}/responses?page=${page}&limit=${limit}`
    );
    return data.data;
  }
}

// 사용법
async function main() {
  const api = new WallaAPI(API_KEY);

  try {
    // 1. 워크스페이스 조회
    const workspaces = await api.getWorkspaces();
    console.log(`Found ${workspaces.length} workspaces`);

    // 2. 폼 조회
    const forms = await api.getForms();
    const firstForm = forms[0]?.forms[0]?.form;

    if (!firstForm) {
      console.log('No forms found');
      return;
    }

    console.log(`Using form: ${firstForm.title} (${firstForm.id})`);

    // 3. 응답 조회
    const responses = await api.getResponses(firstForm.id);
    console.log(`Total responses: ${responses.pagination.totalCount}`);

  } catch (error) {
    console.error('Error:', error.message);
  }
}

main();

Python

import os
import requests
from dotenv import load_dotenv

load_dotenv()

class WallaAPI:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = 'https://api.walla.my/open-api/v1'
        self.headers = {
            'X-WALLA-API-KEY': api_key,
            'Content-Type': 'application/json'
        }

    def request(self, endpoint, method='GET', **kwargs):
        url = f'{self.base_url}{endpoint}'
        response = requests.request(
            method,
            url,
            headers=self.headers,
            **kwargs
        )
        response.raise_for_status()
        return response.json()

    def get_workspaces(self):
        return self.request('/workspaces')['data']

    def get_forms(self):
        return self.request('/forms')['data']

    def get_responses(self, form_id, page=1, limit=20):
        return self.request(
            f'/forms/{form_id}/responses',
            params={'page': page, 'limit': limit}
        )['data']

# 사용법
def main():
    api = WallaAPI(os.getenv('WALLA_API_KEY'))

    try:
        # 1. 워크스페이스 조회
        workspaces = api.get_workspaces()
        print(f'Found {len(workspaces)} workspaces')

        # 2. 폼 조회
        forms = api.get_forms()
        if not forms or not forms[0]['forms']:
            print('No forms found')
            return

        first_form = forms[0]['forms'][0]['form']
        print(f"Using form: {first_form['title']} ({first_form['id']})")

        # 3. 응답 조회
        responses = api.get_responses(first_form['id'])
        print(f"Total responses: {responses['pagination']['totalCount']}")

    except requests.RequestException as e:
        print(f'Error: {e}')

if __name__ == '__main__':
    main()

다음 단계

기본 사용법을 익혔다면, 각 API 레퍼런스도 확인해 보세요.

일반적인 문제

"Authentication failed"

  • API 키가 올바른지 확인하세요
  • X-WALLA-API-KEY 헤더가 포함되어 있는지 확인하세요
  • 올바른 환경의 API 키인지 확인하세요

"Form not found or not published"

  • 폼이 게시 상태인지 확인하세요
  • 폼 ID가 올바른지 확인하세요
  • 해당 워크스페이스에 접근 권한이 있는지 확인하세요

빈 결과가 반환되는 경우

  • 해당 리소스에 데이터가 있는지 확인하세요
  • 올바른 워크스페이스/폼을 조회하고 있는지 확인하세요
  • 필요한 권한이 있는지 확인하세요

자세한 오류 정보는 오류 코드 문서를 참고하세요.

목차