폼 API

폼 관리를 위한 API 레퍼런스

폼 API

폼 API로 워크스페이스 내 폼(설문/프로젝트)의 목록, 상세 정보, 설정 등을 조회할 수 있습니다.

참고: API 키당 시간당 6,000건의 속도 제한이 적용됩니다.

엔드포인트

모든 폼 조회

접근 가능한 모든 워크스페이스의 폼 목록을 반환합니다.

GET /open-api/v1/forms

요청

헤더

  • X-WALLA-API-KEY (필수): API 키
  • Content-Type: application/json

요청 예시

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

응답

성공 응답 (200 OK)

{
  "success": true,
  "data": [
    {
      "workspaceId": "workspace_123",
      "workspaceName": "마케팅 팀",
      "forms": [
        {
          "form": {
            "id": "form_abc",
            "workspaceId": "workspace_123",
            "title": "고객 만족도 설문조사",
            "description": "분기별 고객 피드백 폼",
            "badge": "2024년 1분기",
            "teamId": "team_456",
            "creator": "user_789",
            "lastEditedBy": "user_012",
            "isDeleted": false,
            "createdAt": "2024-01-15T10:30:00Z",
            "updatedAt": "2024-01-20T14:45:00Z"
          },
          "formSettings": {
            // 폼 구성 설정
          },
          "analytics": {
            "submissions": 150
          }
        }
      ]
    }
  ]
}

응답 필드

필드타입설명
successboolean요청 성공 여부
dataarray폼이 포함된 워크스페이스 객체 배열
data[].workspaceIdstring워크스페이스 식별자
data[].workspaceNamestring워크스페이스 이름
data[].formsarray워크스페이스 내 폼 배열
data[].forms[].formobject폼 상세 정보
data[].forms[].formSettingsobject폼 구성 설정 (테마, 언어, 알림 등 폼별 환경설정)
data[].forms[].analyticsobject폼 분석 데이터

오류 응답

  • 403 Forbidden: 인증 실패 또는 권한 없음
  • 500 Internal Server Error: 서버 오류

ID로 폼 조회

특정 폼의 상세 정보를 반환합니다.

GET /open-api/v1/forms/{formId}

파라미터

경로 파라미터

파라미터타입필수설명
formIdstring고유 폼 식별자

요청

요청 예시

curl -X GET "https://api.walla.my/open-api/v1/forms/form_abc" \
  -H "X-WALLA-API-KEY: your_api_key_here" \
  -H "Content-Type: application/json"

응답

성공 응답 (200 OK)

{
  "success": true,
  "data": {
    "id": "form_abc",
    "title": "고객 만족도 설문조사",
    "description": "분기별 고객 피드백 폼",
    "badge": "2024년 1분기",
    "teamId": "team_456",
    "workspaceId": "workspace_123",
    "creator": "user_789",
    "lastEditedBy": "user_012",
    "isDeleted": false,
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-20T14:45:00Z"
  }
}

응답 필드

필드타입설명
successboolean요청 성공 여부
dataobject폼 상세 정보
data.idstring고유 폼 식별자
data.titlestring폼 제목
data.descriptionstring폼 설명
data.badgestring폼 뱃지/라벨
data.teamIdstring연관된 팀 식별자
data.workspaceIdstring부모 워크스페이스 식별자
data.creatorstring생성자 사용자 식별자
data.lastEditedBystring마지막 편집자 사용자 식별자
data.isDeletedboolean삭제 상태
data.createdAtstring (date-time)폼 생성 타임스탬프
data.updatedAtstring (date-time)마지막 업데이트 타임스탬프

오류 응답

  • 403 Forbidden: 인증 실패 또는 권한 없음

    {
      "error": "인증 실패 또는 권한 없음"
    }
  • 404 Not Found: 폼을 찾을 수 없음

    {
      "error": "폼을 찾을 수 없음"
    }
  • 500 Internal Server Error: 서버 오류

    {
      "error": "내부 서버 오류"
    }

폼 필드 조회

특정 폼의 게시된 필드 목록을 반환합니다.

GET /open-api/v1/forms/{formId}/fields

파라미터

경로 파라미터

파라미터타입필수설명
formIdstring고유 폼 식별자 (게시된 폼 ID)

요청

요청 예시

curl -X GET "https://api.walla.my/open-api/v1/forms/form_abc/fields" \
  -H "X-WALLA-API-KEY: your_api_key_here" \
  -H "Content-Type: application/json"

응답

성공 응답 (200 OK)

{
  "success": true,
  "data": {
    "fields": [
      {
        "id": "field_abc123",
        "label": "이름이 무엇인가요?",
        "fieldType": "SHORT_TEXT",
        "outputType": "string"
      },
      {
        "id": "field_xyz789",
        "label": "선호 사항을 선택하세요",
        "fieldType": "CHECKBOX",
        "outputType": "array"
      },
      {
        "id": "field_def456",
        "label": "주소",
        "fieldType": "ADDRESS",
        "outputType": "object"
      }
    ]
  }
}

응답 필드

필드타입설명
successboolean요청 성공 여부
data.fieldsarray필드 객체 배열
data.fields[].idstring고유 필드 식별자
data.fields[].labelstring필드 라벨/질문 텍스트
data.fields[].fieldTypestring필드 타입 (SHORT_TEXT, RADIO, CHECKBOX 등)
data.fields[].outputTypestring출력 스키마 타입 (string, array, object, null)

일반적인 필드 타입:

  • SHORT_TEXT, LONG_TEXT, EMAIL, PHONE, NUMBER, DATE, TIME, URL, RADIO, DROPDOWN → 출력 타입: string
  • CHECKBOX, MULTI_SELECT, FILE_UPLOAD → 출력 타입: array
  • ADDRESS, NAME, PHONE_DETAILED, DATE_RANGE → 출력 타입: object
  • GRID → 출력 타입: grid
  • HEADING, DESCRIPTION, DIVIDER, IMAGE → 출력 타입: null

오류 응답

  • 400 Bad Request: 잘못된 요청
  • 403 Forbidden: 인증 실패 또는 권한 없음
  • 404 Not Found: 폼을 찾을 수 없음
  • 500 Internal Server Error: 서버 오류

필드 상세 정보 조회

특정 필드의 속성, 검증 규칙, 출력 스키마, 조건부 로직 등 전체 상세 정보를 반환합니다.

GET /open-api/v1/forms/{formId}/fields/{fieldId}

파라미터

경로 파라미터

파라미터타입필수설명
formIdstring고유 폼 식별자 (게시된 폼 ID)
fieldIdstring고유 필드 식별자

요청

요청 예시

curl -X GET "https://api.walla.my/open-api/v1/forms/form_abc/fields/field_abc123" \
  -H "X-WALLA-API-KEY: your_api_key_here" \
  -H "Content-Type: application/json"

응답

성공 응답 (200 OK)

{
  "success": true,
  "data": {
    "id": "field_abc123",
    "publishedFormId": "form_abc",
    "label": "이메일 주소가 무엇인가요?",
    "fieldType": "EMAIL",
    "outputSchema": {
      "type": "string",
      "format": "email"
    },
    "properties": {
      "placeholder": "you@example.com",
      "required": true
    },
    "validations": {
      "required": true,
      "email": true
    },
    "validationErrorMessage": {
      "required": "이메일은 필수입니다",
      "email": "유효한 이메일 주소를 입력하세요"
    },
    "branches": [
      {
        "condition": {
          "field": "field_abc123",
          "operator": "contains",
          "value": "@company.com"
        },
        "action": {
          "type": "show",
          "targetField": "field_xyz789"
        }
      }
    ],
    "isResponseMasked": false,
    "responseMaskOptions": null
  }
}

응답 필드

필드타입설명
successboolean요청 성공 여부
data.idstring고유 필드 식별자
data.publishedFormIdstring게시된 폼 식별자
data.labelstring필드 라벨/질문 텍스트
data.fieldTypestring필드 타입 (SHORT_TEXT, RADIO, CHECKBOX 등)
data.outputSchemaobjectJSON Schema 형식의 출력 스키마
data.propertiesobject필드별 속성 (옵션, 플레이스홀더, 필수 등)
data.validationsobject필드의 검증 규칙
data.validationErrorMessageobject사용자 정의 검증 오류 메시지
data.branchesarray조건부 로직/분기 규칙 (nullable)
data.isResponseMaskedboolean프라이버시를 위해 응답이 마스킹되는지 여부 (nullable)
data.responseMaskOptionsobject응답 마스킹 구성 (nullable)

필드 타입별 속성:

필드 타입에 따라 다른 속성이 있습니다:

  • SHORT_TEXT/LONG_TEXT: placeholder, minLength, maxLength, required
  • EMAIL: placeholder, required
  • PHONE: defaultCountryCode, required
  • NUMBER: min, max, step, required
  • RADIO/CHECKBOX/DROPDOWN: options (선택 항목 배열)
  • DATE: minDate, maxDate, format
  • FILE_UPLOAD: maxFiles, maxFileSize, allowedTypes

오류 응답

  • 400 Bad Request: 잘못된 요청
  • 403 Forbidden: 인증 실패 또는 권한 없음
  • 404 Not Found: 폼 또는 필드를 찾을 수 없음
  • 500 Internal Server Error: 서버 오류

필드 설명 조회

특정 필드의 설명/도움말 텍스트를 반환합니다.

GET /open-api/v1/forms/{formId}/fields/{fieldId}/description

파라미터

경로 파라미터

파라미터타입필수설명
formIdstring고유 폼 식별자 (게시된 폼 ID)
fieldIdstring고유 필드 식별자

요청

요청 예시

curl -X GET "https://api.walla.my/open-api/v1/forms/form_abc/fields/field_abc123/description" \
  -H "X-WALLA-API-KEY: your_api_key_here" \
  -H "Content-Type: application/json"

응답

성공 응답 (200 OK)

{
  "success": true,
  "data": {
    "id": "field_abc123",
    "publishedFormId": "form_abc",
    "publishedFormFieldId": "published_field_123",
    "html": "<p>연락 가능한 유효한 이메일 주소를 입력해주세요.</p>",
    "tiptapType": "doc"
  }
}

응답 필드

필드타입설명
successboolean요청 성공 여부
data.idstring필드 식별자
data.publishedFormIdstring게시된 폼 식별자
data.publishedFormFieldIdstring게시된 필드 식별자 (nullable)
data.htmlstring필드 설명 HTML 내용 (nullable)
data.tiptapTypestringTipTap 에디터 타입 (nullable)

오류 응답

  • 400 Bad Request: 잘못된 요청
  • 403 Forbidden: 인증 실패 또는 권한 없음
  • 404 Not Found: 폼 또는 필드 설명을 찾을 수 없음
  • 500 Internal Server Error: 서버 오류

폼 속성 설명

폼 상태

  • isDeleted: 폼이 소프트 삭제되었는지 나타내는 플래그입니다. 삭제된 폼도 API로는 조회할 수 있지만, 메인 인터페이스에서는 숨겨집니다.

폼 뱃지

badge 필드는 폼에 붙이는 사용자 정의 라벨입니다. 주로 다음과 같이 사용됩니다.

  • 버전 번호 (예: "v2.0")
  • 기간 (예: "2024년 1분기", "1월")
  • 상태 표시기 (예: "활성", "초안")
  • 캠페인 이름

감사 추적

폼에는 다음과 같은 감사 추적 정보가 포함됩니다.

  • creator: 폼을 만든 사용자 ID
  • lastEditedBy: 마지막으로 수정한 사용자 ID
  • createdAt: 폼 생성 시각
  • updatedAt: 마지막 수정 시각

코드 예시

JavaScript/TypeScript

interface Form {
  id: string;
  title: string;
  description: string;
  badge: string;
  teamId: string;
  workspaceId: string;
  creator: string;
  lastEditedBy: string;
  isDeleted: boolean;
  createdAt: string;
  updatedAt: string;
}

async function getAllForms(): Promise<any[]> {
  const response = await fetch('https://api.walla.my/open-api/v1/forms', {
    method: 'GET',
    headers: {
      'X-WALLA-API-KEY': process.env.WALLA_API_KEY!,
      'Content-Type': 'application/json'
    }
  });

  if (!response.ok) {
    throw new Error(`HTTP 오류! 상태: ${response.status}`);
  }

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

async function getFormById(formId: string): Promise<Form> {
  const response = await fetch(
    `https://api.walla.my/open-api/v1/forms/${formId}`,
    {
      method: 'GET',
      headers: {
        'X-WALLA-API-KEY': process.env.WALLA_API_KEY!,
        'Content-Type': 'application/json'
      }
    }
  );

  if (!response.ok) {
    throw new Error(`HTTP 오류! 상태: ${response.status}`);
  }

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

// 활성(삭제되지 않은) 폼 모두 가져오기
async function getActiveForms(): Promise<Form[]> {
  const workspaces = await getAllForms();
  const activeForms: Form[] = [];

  workspaces.forEach(workspace => {
    workspace.forms.forEach(formWrapper => {
      if (!formWrapper.form.isDeleted) {
        activeForms.push(formWrapper.form);
      }
    });
  });

  return activeForms;
}

Python

import requests
import os
from typing import List, Dict, Any

class WallaFormsAPI:
    def __init__(self, api_key: str):
        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 get_all_forms(self) -> List[Dict[str, Any]]:
        """모든 워크스페이스의 모든 폼 가져오기"""
        url = f"{self.base_url}/forms"
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()["data"]

    def get_form_by_id(self, form_id: str) -> Dict[str, Any]:
        """ID로 특정 폼 가져오기"""
        url = f"{self.base_url}/forms/{form_id}"
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()["data"]

    def get_active_forms(self) -> List[Dict[str, Any]]:
        """삭제되지 않은 모든 폼 가져오기"""
        workspaces = self.get_all_forms()
        active_forms = []

        for workspace in workspaces:
            for form_wrapper in workspace["forms"]:
                if not form_wrapper["form"]["isDeleted"]:
                    active_forms.append(form_wrapper["form"])

        return active_forms

# 사용법
api = WallaFormsAPI(os.getenv("WALLA_API_KEY"))
forms = api.get_all_forms()
specific_form = api.get_form_by_id("form_abc")

사용 사례

모든 활성 폼 조회

전체 워크스페이스에서 삭제되지 않은 폼만 필터링합니다.

const workspaces = await getAllForms();
const activeForms = workspaces.flatMap(ws =>
  ws.forms
    .filter(f => !f.form.isDeleted)
    .map(f => f.form)
);

워크스페이스별 폼 찾기

특정 워크스페이스의 폼만 가져옵니다.

const workspaces = await getAllForms();
const targetWorkspace = workspaces.find(ws => ws.workspaceId === 'workspace_123');
const forms = targetWorkspace?.forms || [];

폼 분석 데이터 확인

제출 수 등 분석 데이터를 확인합니다.

const workspaces = await getAllForms();
workspaces.forEach(ws => {
  ws.forms.forEach(formWrapper => {
    console.log(`${formWrapper.form.title}: ${formWrapper.analytics.submissions}건의 제출`);
  });
});

다음 단계

목차