errand

> API 문서_

Errand는 현실 세계의 짧은 작업을 사람에게 맡기고, 위치와 시각이 검증된 사진과 구조화된 답변을 돌려줍니다. MCP와 REST 두 가지로 같은 7개 동작을 제공합니다.

기준 URL: https://errand.be

// COVERAGE

지금 서비스되는 곳은 서울 강남 일대뿐입니다. 디스패치 전에 반드시 확인하세요. reachable_workers는 알림을 받게 될 워커 수(앱을 켜 두고 24시간 내 접속, 마지막 위치가 반경 안)이고, online_workers는 지금 이 순간 앱이 열려 있는 수입니다. 판단 기준은 reachable_workers입니다. 0이면 그대로 0이라고 답합니다.

curl -s "https://errand.be/api/public/coverage?lat=37.4979&lng=127.0276&radius_m=3000"

{"online_workers":0,"reachable_workers":3,"dispatchable":true,"radius_m":3000}

// AUTHENTICATION

REST와 개발자용 MCP 연결은 errand.be에서 이메일 인증 후 발급한 er_live_ API 키를 Authorization 헤더로 보냅니다. OAuth를 지원하는 MCP 클라이언트는 정적 키 없이 https://errand.be/api/mcp에 연결할 수 있고, 서버가 OAuth 2.1 인가 서버를 자동으로 알려줍니다. 어떤 방식이든 계정의 건당 보상, 일일 예산, 허용 작업 유형, 허용 구역 상한이 지출 경계로 적용됩니다.

Authorization: Bearer er_live_...

# OAuth-capable MCP clients can connect directly:
https://errand.be/api/mcp

// PRICING

원화 선불입니다. 워커는 reward_krw를 전액 받고, 계정에는 reward_krw + 수수료가 청구됩니다. 수수료는 보상의 20%이고 최소 500원입니다. 디스패치 시점에 전액이 예치되고, 실패·만료·취소 중 어느 경우든 수수료까지 포함해 전액 환불됩니다. 수수료는 완료된 미션에서만 발생합니다.

예: 보상 5,000원 → 청구 6,000원. 보상 10,000원 → 청구 12,000원.

// QUOTE

디스패치는 되돌리기 전에 돈이 나가는 동작입니다. errand_quote는 아무것도 만들지 않고 상한 검사, 커버리지, 잔액, 수수료를 한 번에 계산해 정확한 총 결제액을 돌려줍니다. 에이전트라면 이 숫자를 사용자에게 그대로 보여주고 동의를 받은 뒤에 디스패치하세요. 수수료를 직접 계산하지 마세요. 요율이 바뀌면 낡은 금액으로 동의를 받게 됩니다.

total_charge_krw가 사용자에게 제시할 금액입니다. can_dispatch는 워커가 도달 가능하고 잔액도 충분할 때만 true이고, false면 note에 이유가 담깁니다. balance_sufficient, balance_krw, coverage도 함께 옵니다.

curl -s -X POST https://errand.be/api/v1/quote \
  -H "Authorization: Bearer $ERRAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"task_type":"check","lat":37.4979,"lng":127.0276,"reward_krw":5000}'

{"task_type":"check","reward_krw":5000,"platform_fee_krw":1000,
 "total_charge_krw":6000,"balance_krw":75900,"balance_sufficient":true,
 "coverage":{"online_workers":0,"reachable_workers":1,"dispatchable":true},
 "can_dispatch":true,
 "note":"Quote is ready. Present the exact total_charge_krw to the user before calling errand_dispatch."}

// OPERATIONS

MCP 도구 이름과 REST 엔드포인트가 1대1로 대응하고, 인자와 응답이 같습니다.

MCP 도구REST동작
errand_check_coverageGET /api/v1/coverage반경 안에 알림 가능한 워커가 있는지 확인
errand_list_capabilitiesGET /api/v1/capabilities잔액, 상한, 허용 작업 유형, 수수료 체계
errand_quotePOST /api/v1/quote정확한 총 결제액과 진행 가능 여부. 아무것도 만들지 않음
errand_dispatchPOST /api/v1/dispatches미션 생성. 예치가 일어남
errand_get_statusGET /api/v1/dispatches/{id}진행 상태와 타임라인
errand_get_resultGET /api/v1/dispatches/{id}/result증거, 답변, 판정
errand_cancelPOST /api/v1/dispatches/{id}/cancel모집 중일 때만 취소. 전액 환불

// DISPATCH

title, instructions, validation_criteria, report_fields[].label은 워커가 폰에서 읽습니다. 한국어로 작성하세요. 규칙을 어기면 VALIDATION 오류와 함께 어떤 필드가 문제인지 issues에 담겨 돌아옵니다.

필드필수규칙
task_typecheck · verify · photograph · queue · pickup
title4–120자. 워커 목록에 보이는 한 줄
instructions10–2000자. 현장에서 무엇을 어떻게 할지
validation_criteria10–1000자. 사진이 무엇을 보여야 통과인지. AI가 이 기준으로 판정
lat / lng미션 지점 좌표
radius_m100–10000. 알림 반경. 3000이 무난
reward_krw1000–200000. 키의 건당 상한 이하여야 함
expires_in_minutes10–1440. 이동 시간을 고려해 120 이상 권장
address_hint워커에게 보여줄 장소 설명
report_fields최대 5개. 워커가 현장에서 답할 질문. key / label / type(text·number) / unit / placeholder. 수량이면 unit을 꼭 넣을 것
webhook_urlhttps. 종결 시 mission.* 이벤트 수신
curl -s -X POST https://errand.be/api/v1/dispatches \
  -H "Authorization: Bearer $ERRAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "task_type": "check",
    "title": "강남역 11번 출구 팝업 대기줄 확인",
    "instructions": "11번 출구 앞 팝업스토어 입구로 가서 대기줄 전체가 보이도록 사진을 한 장 찍어주세요.",
    "validation_criteria": "팝업스토어 간판과 대기줄이 한 장에 보일 것. 줄이 없으면 비어 있는 입구가 보일 것.",
    "lat": 37.4979, "lng": 127.0276,
    "address_hint": "강남역 11번 출구 앞",
    "radius_m": 3000,
    "reward_krw": 5000,
    "expires_in_minutes": 180,
    "report_fields": [
      { "key": "wait_count", "label": "대기 인원", "type": "number", "unit": "명" }
    ]
  }'

{"dispatch_id":"…","status":"open","reward_krw":5000,"fee_krw":1000,
 "escrowed_krw":6000,"workers_notified":3,"expires_in_minutes":180}

// LIFECYCLE

open(모집 중) → accepted(수락, 이동 중) → arrived(GPS로 현장 확인) → submitted(제출, 검증 중) → completed(통과, 워커 지급). 종결 실패는 failed(2회 시도 모두 불합격), expired(마감까지 아무도 완료 못 함), cancelled 셋이고 모두 전액 환불됩니다. 폴링 대신 webhook_url을 주면 mission.completed / mission.failed / mission.cancelled / mission.expired가 전송됩니다.

// VERIFICATION

사진은 앱 카메라로만 찍을 수 있고 갤러리 업로드는 막혀 있습니다. 서버가 촬영 위치와 시각을 먼저 확인하고, 그다음 AI가 validation_criteria에 적힌 기준으로 사진을 판정합니다. 한 미션에 두 번까지 시도할 수 있고, 두 번 모두 불합격이면 미션이 실패로 종결되며 전액 환불됩니다.

// RESULT

워커가 입력한 답변, 증거 사진, 위치·시각 검사값, AI 판정이 함께 돌아옵니다. 사진 URL은 서명된 링크이고 1시간 뒤 만료되니 받는 즉시 내려받거나 보여주세요. 아직 제출 전이면 result가 null이고 note가 이유를 설명합니다.

{
  "status": "completed",
  "verdict": { "passed": true, "score": 0.95, "feedback": "…" },
  "answers": { "wait_count": 12 },
  "evidence": {
    "photo_urls": ["https://…signed…"],
    "gps": { "lat": 37.4980, "lng": 127.0275, "accuracy_m": 8 },
    "distance_from_task_m": 14,
    "captured_at": "2026-09-08T14:12:33+09:00",
    "checks": { "distance_m": 14, "capture_age_min": 1.2,
                "exif_gps_present": true, "failures": [] }
  }
}

// ERRORS

모든 오류는 { "error": CODE, "message": "…" } 형태입니다.

HTTP코드
401UNAUTHORIZED키가 없거나 폐기됨
402INSUFFICIENT_BALANCE잔액 부족. 대시보드에서 충전
403CAP_MAX_REWARD · CAP_DAILY_BUDGET · CAP_TASK_TYPE · CAP_AREA키의 상한을 넘음. 재시도하지 말고 보상을 낮추거나 소유자에게 상한 상향을 요청
400VALIDATION · BAD_JSON필드 규칙 위반. issues에 어떤 필드인지 있음
404NOT_FOUND없는 dispatch id이거나 다른 계정 소유
409INVALID_TRANSITION · TASK_TAKEN · WORKER_BUSY지금 상태에서 불가능한 동작. 수락된 뒤에는 취소할 수 없음
429RATE_LIMITED요청이 잦음. 잠시 후 재시도

// RATE_LIMITS

공개 커버리지 엔드포인트는 IP당 분당 60회입니다. 초과하면 429가 돌아옵니다. 인증이 필요한 엔드포인트는 키의 일일 예산이 실질적인 한도입니다.

// MCP

무상태 Streamable HTTP입니다. 공식 MCP 레지스트리에 be.errand/errand로 등록돼 있습니다. OAuth-capable 클라이언트는 URL만 연결하면 OAuth 2.1을 자동 discovery하고, CLI/개발 환경에서는 er_live_ API 키를 계속 사용할 수 있습니다.

# OAuth-capable clients: connect to the URL directly
https://errand.be/api/mcp

# Developer/CLI fallback with an API key
claude mcp add --transport http errand https://errand.be/api/mcp \
  --header "Authorization: Bearer $ERRAND_API_KEY"

// SUPPORT

상한을 올리고 싶거나, 커버리지 밖 지역이 필요하거나, 첫 미션을 어떻게 쓸지 모르겠다면 support@errand.be로 보내주세요. 초기 서비스라 사람이 직접 답합니다.