REST API
앱이 프로젝트, 폴더, 제품, Enterprise 조직, Open Guest 리드에 대해 하는 일을 자체 소프트웨어에서 실행하고, Developer 페이지에서 요청을 시험해 보고, 이벤트가 발생할 때 웹훅을 받으세요.
REST API를 사용하면 앱이 하는 일을 자체 소프트웨어에서 할 수 있습니다. 프로젝트와 측정값, 폴더, 제품 카탈로그를 다루고, Enterprise에서는 Enterprise 페이지에서 운영하는 조직을, Open Guest에서는 게스트 링크, 게스트 프로젝트, 견적 요청을 다룹니다. 응답은 JSON입니다. 모든 필드와 예제가 담긴 전체 레퍼런스는 API 문서이며, 이 페이지는 그 개요입니다.
앱에서 문서를 열려면 개발자 > REST API로 이동하여 문서 보기을 누르세요.
기본 URL#
모든 요청은 다음 주소로 보냅니다.
https://api.measuremaponline.com/api/v2
인증#
모든 요청의 Authorization 헤더에 API 키를 그대로 보냅니다. 키는 Developer
페이지에서 만듭니다. API 키를 참고하세요.
curl https://api.measuremaponline.com/api/v2/projects/YOUR_PROJECT_ID \
-H "Authorization: YOUR_API_KEY"
각 요청은 키의 접근 권한(예: Projects 읽기), 구독, 웹 페이지에서 보낸 요청이라면 키의 웹사이트 제한에 따라 확인됩니다. 데이터를 변경할 수 있는 키는 서버에 보관하세요. 키를 안전하게 보관하기를 참고하세요.
라이브와 샌드박스#
두 환경의 기본 URL은 하나입니다. 환경은 키가 결정합니다. 샌드박스 키는 라이브 키에는 보이지 않는 샌드박스 프로젝트, 폴더, 제품을 읽고 씁니다. 조직의 사용자, 시트, 팀은 두 환경에서 같으므로 변경하려면 라이브 키가 필요합니다. 샌드박스 키로 만든 게스트 프로젝트에는 요금이 청구되지 않으며, 샌드박스 프로젝트는 웹사이트에 임베드할 수 없습니다. 토큰은 자신이 속한 환경을 알려 줍니다.
API가 다루는 범위#
| 그룹 | 엔드포인트 | 필요한 키 접근 권한 |
|---|---|---|
| 로그인 토큰 | POST /auth/token, POST /auth/iframe/token |
임베드된 지도(Open Guest에서는 게스트 프로젝트) |
| 계정 | GET /account로 계정의 플랜, 좌석, 키. GET /usage로 최근 30일의 API 요청과, Open Guest에서는 해당 기간의 게스트 프로젝트와 예산 |
계정: 읽기 |
| 프로젝트와 폴더 | 프로젝트(GET /projects, trashed=true로 휴지통)와 폴더(GET /folders), 프로젝트와 그 측정값(/projects/{pid}/data), 댓글, .mmp 파일(/projects/{pid}/mmp) 가져오기, 프로젝트와 폴더 생성, 업데이트, 이동, 프로젝트 병합(POST /projects/merge), 휴지통로 삭제 및 복원(POST /projects/{pid}/restore), 프로젝트의 버전(/projects/{pid}/versions), 댓글 삭제 및 복원, 이메일로 프로젝트나 폴더 공유(PUT /projects/{pid}/members) |
프로젝트: 읽기는 읽기, 변경은 읽기 및 변경 |
| 프로젝트 파일과 사본 | 앱의 형식으로 프로젝트 내보내기(POST /projects/{pid}/export) 또는 PDF 보고서 가져오기(GET /projects/{pid}/pdf), 둘 다 24시간 동안 유효한 링크로 제공됩니다. 프로젝트 복사 또는 템플릿 만들기(POST /projects/{pid}/copy) |
프로젝트: 읽기. 복사는 읽기 및 변경. 보고서의 가격은 제품: 읽기가 필요 |
| 견적 | 프로젝트의 견적을 항목별로(GET /projects/{pid}/estimate) |
프로젝트 및 제품: 읽기 |
| 제품 | GET /products, GET /products/{id}, 생성, 수정, DELETE /products/{id}로 보관 |
제품: 읽기 또는 읽기 및 변경 |
| 프로필 | 프로필과 이메일 설정(/account/profile). 파트너의 고객에게는 요금제를 누가 지불하는지와 초대(/account/partner) |
계정: 읽기, 읽기 및 변경 |
| 가져오기 | 프로젝트로 파일 가져오기(POST /projects/{pid}/imports). 앱의 가져오기처럼 추가하거나 교체한 뒤 진행 상황을 확인합니다 |
프로젝트: 읽기 및 변경 |
| 키와 웹훅 | 계정의 API 키(/keys: 나열, 취소, 웹사이트. 키 전체는 반환하지 않으며 호출하는 키의 권한을 넘지 않음)와 웹훅(/webhook) |
개발자: 읽기, 읽기 및 변경 |
| 파트너 | 고객과 초대, 고객의 요금제, 좌석, 예산, 결제, 청구서(/partner) |
고객: 읽기, 읽기 및 변경 |
| Enterprise: 사용자, 초대, 시트, 팀 | 사용자(/enterprise/users): 목록, 역할이나 세부 정보 변경, 비활성화와 활성화, 모든 곳에서 로그아웃, 조직에서 제거, 삭제, 팀 설정, 프로젝트 넘기기. 초대(/enterprise/invitations): 초대, 목록, 다시 보내기, 철회. 시트(GET /enterprise/seats). 팀(/enterprise/teams). 조직의 모든 프로젝트(GET /enterprise/projects)와 팀의 프로젝트 |
사용자: 읽기 또는 읽기 및 변경, 프로젝트에는 프로젝트 필요 |
| Enterprise: 조직 | 조직의 프로필과 정책(/enterprise/organization), 싱글 사인온(GET /enterprise/sso), 활동 로그(GET /enterprise/activity), 시트 구매 및 반납(PUT /enterprise/seats) |
조직: 읽기 또는 읽기 및 변경 |
| Open Guest | 게스트 링크(/open-guest/link: 가져오기, 만들기 또는 교체, 일시 중지, 폴더 선택), 게스트 프로젝트(/open-guest/projects: 목록, 방문자용으로 시작, 가져오기), 견적이 포함된 견적 요청(/open-guest/requests), 이번 기간 사용량(GET /open-guest/usage)과 예산(PUT /open-guest/budget) |
게스트: 읽기, 변경하려면 읽기 및 변경 |
알아 둘 점은 다음과 같습니다.
- 키는 자신의 계정 프로젝트에 접근하며, Enterprise에서는 조직 사용자의 프로젝트에도 접근합니다.
- 프로젝트를 삭제하면 앱에서처럼 휴지통로 이동하며, 만든 사람만 삭제할 수 있습니다. 완전히 삭제하려면 휴지통에서
forever=true로 삭제하세요. 폴더를 삭제하면 그 안의 프로젝트가 휴지통로 이동합니다. - 프로젝트의 측정값에서 도형은
productIds에 제품을 순서대로 나열하며,productId는 그중 첫 번째입니다. /projects/{pid}/mmp는 앱이 내보내는 것과 같은.mmp파일을 제공합니다. 스키마는 github.com/blueblinkone/mmp-validator에 공개되어 있습니다. 새 요소는 항상 선택 사항으로만 추가되므로, 이전 파일용으로 작성된 리더도 계속 작동합니다.- Open Guest에서 API로 시작한 게스트 프로젝트(
POST /open-guest/projects)는 게스트 링크에서 시작한 프로젝트처럼 Open Guest 사용량과 예산에 포함됩니다. - Open Guest에서 게스트 링크 섹션에는
서버와 페이지용 코드가 담긴 Open Guest API 가이드가 있습니다. 서버가
라이브 키로
POST /auth/token에서 토큰을 받고, 방문자의 정보가 채워진 방문자 전용 새 프로젝트로 방문자를 보냅니다. - 사람들은 Enterprise 페이지에서처럼 초대(
POST /enterprise/invitations)로만 조직에 참여합니다. 계정이 없는 사람은 계정이 만들어지고 비밀번호는 직접 정합니다. API는 계정을 만들거나 비밀번호를 설정하지 않습니다. - 사용자를 제거하면(
POST /enterprise/users/{uid}/remove) 계정은 그대로 남고, 삭제하면(DELETE /enterprise/users/{uid}) 계정이 삭제됩니다. 어느 쪽이든 그 사용자가 만든 작업은 조직에 남으며, 관리자가 공유하는 사용자 이름의 새 폴더에 들어갑니다. - 게스트가 견적을 요청하면
GET /open-guest/requests/{pid}가 게스트가 누구인지, 무엇을 적었는지, 무엇을 측정했는지, 그리고 제품: 읽기이 있으면 견적 자체를 응답합니다. - Open Guest에서 토큰은 방문자를 위한 게스트 프로젝트를 시작합니다. 방문자를
임베드 지도에 로그인시키는
POST /auth/iframe/token은 Enterprise 키 전용입니다. - 제품은 API로 삭제되지 않고 보관만 되며, 제품의 원가는 절대 반환되지 않습니다.
- 지적도 필지는 API에 포함되지 않습니다.
응답과 오류#
성공한 요청은 상태 200과 JSON으로 응답합니다(.mmp 내보내기는 XML로
응답합니다). 실패한 요청은 오류 상태와 다음과 같은 본문으로 응답합니다.
{"errorCode": "insufficient_scope", "errorMessage": "This API key does not have the scope required for this endpoint"}
| 상태 | errorCode |
확인할 사항 |
|---|---|---|
| 400 | invalid_body, invalid_uid, invalid_project_id, pagination_invalid_page_number, pagination_invalid_page_limit |
요청의 값이 없거나 허용되지 않습니다. 예를 들어 페이지별 목록의 page와 limit입니다. |
| 401 | unauthorized_action |
키가 허용하지 않는 웹사이트의 웹 페이지에서 요청을 보냈거나, 항목이 내 계정이나 내 멤버의 것이 아닙니다. |
| 402 | budget_limit_reached |
Open Guest: 예산 한도에 도달하여 이 기간에는 더 이상 게스트 프로젝트를 만들 수 없습니다. |
| 403 | invalid_api_key |
Authorization 헤더에 키를 보내지 않았거나, 키를 알 수 없거나 폐기되었거나, 교체 후 24시간이 지났습니다. |
| 403 | api_key_suspended |
계정의 API 접근이 중지되었습니다. 지원팀에 문의하세요. |
| 403 | subscription_expired, invalid_subscription |
구독이 활성 상태가 아니거나, 플랜에 API가 없습니다. |
| 403 | insufficient_scope |
키에 이 엔드포인트에 필요한 접근 권한이 없습니다. |
| 403 | scope_not_in_plan |
플랜에 이 엔드포인트가 포함되어 있지 않습니다. 예를 들어 Open Guest에서의 Enterprise 섹션입니다. |
| 403 | embed_needs_enterprise |
임베드 지도는 Enterprise 플랜에 포함됩니다. Open Guest 키는 자신의 게스트 프로젝트만 엽니다. |
| 404 | not_found, project_not_found, user_not_found |
항목이 없거나, 그 사람이 조직의 사용자가 아닙니다. |
| 409 | enterprise_add_users_limit |
초대할 때: 모든 시트가 사용 중이고 자동 시트가 꺼져 있습니다. |
| 409 | project_not_in_trash |
휴지통에 없는 프로젝트에 대해 복원 또는 영구 삭제가 요청되었습니다. |
| 429 | too_many_requests |
한 시간에 600개가 넘는 토큰. 잠시 기다린 후 다시 시도하세요. |
| 500 | server_error |
요청을 완료하지 못했습니다. 보낸 ID를 확인하고 다시 시도하세요. 계속되면 지원팀에 문의하세요. |
Developer 페이지에서 API 시험해 보기#
개발자 > API 체험는 내 키로 실제 요청을 보내고 돌아오는 응답을 그대로 보여 줍니다.
- 라이브 또는 **샌드박스**를 선택합니다.
- "내 프로젝트 나열", "측정값 가져오기", "계정 가져오기" 같은 **엔드포인트**를 고릅니다. 목록에는 플랜에 포함된 엔드포인트가 표시됩니다.
- 매개변수를 입력합니다. 프로젝트나 제품은 키가 읽을 수 있는 항목 중에서 이름으로 선택하며, 사람이 필요한 곳에는 내 계정이 자동으로 채워집니다.
- 요청 보내기를 누릅니다. 상태와 응답이 아래에 표시됩니다.
읽기 요청만 제공되므로 시험해 보아도 아무것도 바뀌지 않으며, 이 요청은 사용량에 집계되지 않습니다. 키에 엔드포인트가 필요로 하는 접근 권한이 없으면 페이지가 403으로 응답할 것이라고 경고합니다.
웹훅#
웹훅은 알림 이메일이 나에게 알려 주듯이 무언가 발생했을 때 서버에 알려 줍니다. 웹훅은 Enterprise 및 Open Guest 플랜에 포함됩니다.
웹훅 설정하기#
개발자 > 웹훅에서 다음을 진행합니다.
- **엔드포인트 URL**을 입력합니다. 인터넷에서 접근할 수 있는
https://주소입니다. 사설 네트워크의 주소는 거부되며, 이는 모든 전송 전에 다시 확인됩니다. - 받고 싶은 **이벤트**를 선택합니다(이벤트 참고). 새 엔드포인트는 플랜이 보내는 이벤트로 시작하며, 최소한 하나는 선택되어 있어야 합니다.
- 저장를 누릅니다. 처음에는 페이지에 서명 비밀 전체가 표시됩니다. 그때 복사하세요. 이후에는 마지막 몇 글자만 표시됩니다.
- 테스트 이벤트 보내기를 누르고 이벤트를 선택합니다.
테스트는 이벤트가 선택되어 있지 않거나 엔드포인트가 꺼져 있어도 해당 이벤트의
샘플을 임의의 값과 data의 "test": true와 함께 저장된 엔드포인트로
보냅니다. 모든 전송을 중단하려면 제거를 누르세요. 엔드포인트와 비밀 키가 삭제됩니다.
설정 아래의 **웹훅 참조**에는 수신 측을 작성하는 데 필요한 내용이 있습니다. 헤더와 본문, Node.js, Python, PHP로 서명을 확인하는 코드, 모든 이벤트의 예제 데이터입니다.
서버가 받는 것#
각 이벤트는 엔드포인트로 보내는 JSON 본문의 POST 한 번입니다.
{"id": "evt_3f9a1c2b7d4e5f60718293a4", "type": "project.created", "created": 1790000000000, "data": { ... }}
id는 이벤트마다 고유하고, created는 이벤트가 발생한 시점으로 1970년 1월
1일(UTC) 이후의 밀리초이며, data에 담기는 내용은 이벤트에 따라 다릅니다.
요청에는 다음 헤더도 있습니다.
| 헤더 | 값 |
|---|---|
X-MMO-Event |
이벤트 이름이며 본문의 type과 같습니다. |
X-MMO-Delivery |
이벤트의 id. |
X-MMO-Signature |
t=<milliseconds>,v1=<hex>: 전송에 서명한 시점과 그 서명. |
User-Agent |
MeasureMapOnline-Webhooks/1 |
- 오래 걸리는 작업 전에 8초 안에 2xx 상태로 응답하세요. 그 밖의 상태, 리디렉션, 시간 초과는 실패로 간주됩니다.
- 각 이벤트는 한 번만 전송되며 재시도되지 않습니다. 섹션에 **마지막 전송**와 **연속 실패**가 표시됩니다.
- 연속으로 10번 실패하면 엔드포인트가 꺼지고 소유자에게 이메일이 갑니다. 서버를 고친 다음 저장를 눌러 다시 켜세요.
- 가끔 이벤트가 두 번 도착하거나 순서가 바뀌어 도착합니다.
id로 중복을 무시하고created로 이벤트의 순서를 정하세요.
서명 확인하기#
주소를 아는 사람은 누구나 그 주소로 전송할 수 있으므로, 신뢰하기 전에 모든 전송을 확인하세요.
X-MMO-Signature헤더를 쉼표에서 나누어t와v1로 만듭니다.- 서명 비밀 키를 키로 하여
t, 마침표, 원본 요청 본문의 HMAC-SHA256을 계산하고 16진수로 표기합니다. - 결과를
v1과 상수 시간 비교로 비교합니다. t가 현재 시각에서 5분 넘게 벗어나 있으면 전송을 거부합니다.t는 밀리초 단위입니다.
본문은 도착한 그대로 사용하세요. JSON을 파싱했다가 다시 쓰면 내용이 달라져 서명이 일치하지 않습니다.
비밀 교체은 비밀 키를 즉시 교체하고 새 키 전체를 한 번 표시합니다. 교체하는 즉시 서버를 업데이트하세요.
이벤트#
| 이벤트 | 전송되는 시점 |
|---|---|
project.created |
내 계정에 프로젝트가 만들어질 때. 앱, API 또는 임베드에서. |
project.deleted |
프로젝트가 영구 삭제될 때(휴지통으로 이동하는 것은 해당하지 않음). |
project.comment.added |
프로젝트에 누군가 의견을 남길 때. 보통 고객의 답변입니다. |
guest.project.created (Open Guest) |
게스트가 내 링크나 API를 통해 프로젝트를 시작할 때. 게스트의 이메일 주소를 알고 있는 경우에만. |
guest.measurement.completed (Open Guest) |
게스트가 측정을 마치고 연락처를 남길 때. |
budget.warning_reached (Open Guest) |
종량제 지출이 경고 임계값을 넘을 때. |
budget.limit_reached (Open Guest) |
종량제 지출이 한도에 도달할 때. 이후 게스트 프로젝트는 거부됩니다. |
enterprise.user.created (Enterprise) |
SSO를 포함해 조직에 좌석이 추가될 때. |
도움이 더 필요하신가요?
지원팀에 어떤 작업을 하려고 했는지 알려 주세요. 스크린샷이 있으면 도움이 됩니다.