빠른 시작
몇 분 안에 첫 API 호출을 해 보세요.
이 페이지에서는 키가 없는 상태에서 시작해 게시된 채용 공고를 모두 읽고, 그다음 전체를 다시 읽지 않고도 사본을 최신으로 유지하는 방법까지 안내합니다. 처음 단계에는 curl이, 페이지 넘기기 예제에는 Python이 필요합니다. 설치할 SDK는 없습니다. API는 일반 HTTPS와 JSON으로 동작합니다.
키 만들기
Tahoe에서 설정을 열고 개발자를 선택한 뒤 키 만들기를 누르세요. 워크스페이스의 소유자 또는 관리자여야 합니다. 다음을 정합니다.
- 키에 필요한 스코프(필요한 만큼만 가장 좁게 선택하세요)
test키인지live키인지, 그리고 “Acme HRIS sync”처럼 키에 붙일 이름. 이름은 사람이 아니라 키를 보관할 시스템을 기준으로 지으세요.- 키를 쓸 기간, 그리고 선택 사항으로 키를 사용할 IP 주소나 대역
키는 만든 워크스페이스를 읽습니다. 설정에 개발자 탭이 없다면 [email protected]으로 문의해 주세요.
키로 할 수 있는 일 확인하기
연동 코드를 쓰기 전에 키 자체에 대해 API에 물어보세요. GET /me를 호출하면 “왜 호출이 실패하지?”라는 질문에 한 줄로 답을 얻을 수 있습니다.
export TAHOE_API_KEY="thk_live_..."
curl -s https://tahoe.workonward.com/api/partner/v1/me \
-H "Authorization: Bearer $TAHOE_API_KEY"{
"object": "credential",
"id": "pk_9tRc4mQx7Lb2",
"name": "Acme HRIS sync",
"environment": "live",
"scopes": ["applications:read", "events:read", "jobs:read"],
"workspace_scope": "list",
"workspace_ids": ["wsp_4Kd8sPm2Qx7L"],
"workspace_id_required": false,
"expires_at": "2026-12-08T10:14:22.510Z",
"api_version": "2026-09-09"
}다음 세 필드를 확인하세요.
scopes: 키가 읽을 수 있는 범위입니다.workspace_ids: 키가 접근할 수 있는 워크스페이스입니다.workspace_id_required: 모든 호출에서?workspace_id=로 워크스페이스를 지정해야 하는지 여부입니다. 대부분의 키는 워크스페이스 하나에 속하므로 이 값은false입니다.
채용 공고 한 페이지 읽기
리스트는 한 번에 한 페이지씩 반환됩니다. 페이지를 요청한 다음, next_cursor가 null이 될 때까지 따라가세요.
curl -s "https://tahoe.workonward.com/api/partner/v1/jobs?status=published&limit=25" \
-H "Authorization: Bearer $TAHOE_API_KEY"{
"object": "list",
"data": [
{
"object": "job",
"id": "job_7Kd2mXq4Rp8v",
"workspace_id": "wsp_4Kd8sPm2Qx7L",
"slug": "field-coordinator-a41f",
"status": "published",
"title": "Field Coordinator",
"department": "Operations",
"employment_type": "full_time",
"location_type": "onsite",
"locations": ["Columbus, Ohio"],
"experience_level": "mid",
"years_min": 2,
"years_max": 5,
"accept_applications": true,
"summary": "Run day-to-day site schedules for our Ohio crews.",
"source": {
"system": "tahoe_native",
"external_id": null,
"company_name": null,
"company_logo_url": null,
"canonical_url": null
},
"published_at": "2026-08-14T09:02:11.004Z",
"created_at": "2026-08-12T15:41:07.882Z",
"updated_at": "2026-09-08T11:20:45.331Z",
"links": { "self": "/api/partner/v1/jobs/job_7Kd2mXq4Rp8v" }
}
],
"has_more": true,
"next_cursor": "cur_eyJrIjoiMjAyNi0wOC0xNFQwOTowMjoxMVoiLCJpIjoiam9iXzdLZDJt..."
}끝까지 페이지 넘기기
아래 반복문은 게시된 채용 공고를 모두 읽습니다. 경로와 필터만 바꾸면 모든 리스트 엔드포인트에 그대로 쓸 수 있습니다.
import os
import requests
BASE = "https://tahoe.workonward.com/api/partner/v1"
SESSION = requests.Session()
SESSION.headers["Authorization"] = f"Bearer {os.environ['TAHOE_API_KEY']}"
def page_all(path, **filters):
"""Yield every row from a list endpoint, following next_cursor."""
cursor = None
while True:
# Send the same filters on every page, plus the cursor. A cursor is
# bound to the filters it came from, so changing one mid-loop is
# refused with invalid_cursor.
params = dict(filters)
if cursor:
params["cursor"] = cursor
response = SESSION.get(f"{BASE}{path}", params=params, timeout=30)
response.raise_for_status()
body = response.json()
yield from body["data"]
cursor = body.get("next_cursor")
if not cursor:
return
for job in page_all("/jobs", status="published", limit=100):
print(job["id"], job["title"])모든 페이지에 같은 필터를 보내세요. 페이지 사이에 limit은 바꿔도 되지만, 필터가 바뀌면 커서가 무효가 됩니다(400 invalid_cursor). 커서는 1시간 뒤에 만료되기도 하므로, 중간에 멈추지 말고 한 번에 끝까지 읽으세요.
변경 사항 따라가기
전체 사본을 만든 뒤에는 워크스페이스 전체를 정해진 주기로 다시 읽지 마세요. 대신 변경 피드를 읽으세요. 변경 피드는 모든 변경을 오래된 것부터 순서대로 보여 줍니다.
curl -s "https://tahoe.workonward.com/api/partner/v1/events?limit=100&type=job.published,job.updated,job.closed" \
-H "Authorization: Bearer $TAHOE_API_KEY"각 이벤트에는 sequence 번호가 있습니다. 마지막으로 처리한 이벤트의 sequence를 저장해 두고, 다음에는 그 뒤부터 읽으세요.
curl -s "https://tahoe.workonward.com/api/partner/v1/events?after=48213&limit=100&type=job.published,job.updated,job.closed" \
-H "Authorization: Bearer $TAHOE_API_KEY"sequence 번호가 동기화 위치입니다. 타임스탬프는 동기화 위치가 될 수 없습니다. 여러 프로세스가 동시에 변경을 기록하므로 시간 순서가 조금씩 뒤바뀌어 도착할 수 있기 때문입니다. 이 작업에는 events:read 스코프와 함께, 변경 소식을 받으려는 각 리소스의 스코프가 필요합니다.