본문으로 건너뛰기

Era API

Era API의 사용 가능한 엔드포인트, 인증 헤더, 페이지네이션, 제한에 대해 알아보세요.

마지막 업데이트: 2026년 9월 5일

아직 베타입니다

이 엔드포인트들은 오늘 기준으로 동작하지만, API는 아직 발전하는 중이라 일부 세부 사항이 바뀔 수 있습니다. 이 페이지가 마지막으로 언제 수정됐는지는 상단의 최종 수정일을 확인하세요.

빠른 시작

시작하기 전에 Era 계정과 연결된 금융기관이 최소 하나 필요합니다. 연결이 없으면 이 엔드포인트들이 돌려줄 것이 없습니다.

  1. 1

    Era에 로그인하고, 아직이라면 금융기관을 연결합니다.

  2. 2

    대시보드에서 API 키를 열고 키를 만듭니다. 범위는 처음에 전부 체크되어 있으니 필요 없는 것을 해제하세요. 이 엔드포인트들에는 banking:read만 남기면 됩니다. 만료 기간도 고르는데, 만료되지 않는 선택지는 없습니다.

  3. 3

    키를 복사합니다. 한 번만 보여 주고, 다시 보여 줄 수 없습니다. 복사해서 시크릿 매니저 같은 안전한 곳에 보관하세요. 키를 잃어버리면 다시 볼 수 없습니다. 대신 새 키를 만드세요.

  4. 4

    요청 헤더에 담아 보냅니다.

cURL

curl "https://forge.era.app/api/banking/transactions?page=1&pageSize=20" \
  -H "X-API-Key: fmk_your_key_here"

응답 · 200

{
  "transactions": [],
  "pagination": {
    "currentPage": 1,
    "pageSize": 20,
    "totalItems": 412,
    "totalPages": 21
  },
  "historyWindowApplied": true,
  "historyWindowFloorDate": "2026-06-28",
  "historyWindowHiddenCount": 137,
  "historyWindowEarliestDate": "2024-03-02",
  "historyWindowDegraded": false
}

인증

키는 다음 두 가지 방법 중 하나로 보내세요:

인증 방법
방법자격 증명
헤더X-API-Key: fmk_your_key_here
베어러 토큰Authorization: Bearer fmk_your_key_here

모든 요청은 TLS로 암호화됩니다.

키는 만료되고, 만들 때 얼마 뒤에 만료될지 고릅니다. 최대는 무료 요금제 90일, 유료 요금제 365일입니다. 만료되지 않는 선택지는 없으니, 이 위에 무언가를 만든다면 만료 전에 키를 교체할 계획이 필요합니다.

응답 헤더

요청 ID는 모든 응답에 들어갑니다. 속도 제한 헤더는 Era가 계량한 호출에 붙습니다. Era가 사용량을 측정하지 못하면 호출을 그대로 처리하고 이 헤더는 하나도 보내지 않습니다.

응답 헤더
헤더설명
fly-request-id

요청을 고유하게 식별하는 ID입니다. 특정 요청에 대해 지원팀에 문의할 때 이 값을 함께 알려주세요. 참고: 요청 ID

X-RateLimit-Limit

요금제의 하루 예산입니다.

X-RateLimit-Remaining

하루 예산에서 남은 양입니다. 0 아래로 내려가지 않습니다.

X-RateLimit-Reset

하루 예산에서 다음 요청이 비는 시각을 Unix 타임스탬프 초로 알려줍니다. 분당 버스트 상한에는 전용 헤더가 없습니다. 참고: 제한

Retry-After429에만

요청을 거절한 상한을 기준으로, 다시 시도하기 전에 기다릴 초입니다. 참고: 제한

오류

이 API가 반환하는 오류 상태 코드는 다음과 같습니다:

  • 400

    잘못된 입력: 잘못된 파라미터, 비어 있거나 100개를 넘는 일괄 업데이트, 또는 같은 호출에서 같은 필드를 설정하면서 동시에 지우는 쓰기.

  • 401

    키가 없거나 파싱할 수 없는 키입니다. X-API-Key 헤더나 베어러 토큰으로 보내세요.

  • 402

    플랜 쿼터에 걸렸습니다 — 오늘 기준으로는 카테고리 생성에만 해당합니다. 얼마나 빨리 호출하느냐가 아니라 무엇을 만드느냐의 문제라서, 기다려도 풀리지 않고 상위 요금제로 올리면 풀립니다. 너무 빨리 호출해서 걸리는 건 429입니다.

  • 403

    키가 이 호출에 필요한 범위를 지니지 않았거나 — 두 거래 쓰기 중 하나에서 id가 다른 사람의 것이거나 아예 존재하지 않는 경우입니다. API는 이 둘을 구분하지 않습니다.

  • 404

    존재하지 않는 계좌입니다. 잔액 엔드포인트만 이 상태를 반환합니다. 어떤 계좌도 가리키지 않는 accountGroupKey나 아예 키 형태가 아닌 값은 본문 없이 404로 돌아옵니다. 거래는 404를 반환하지 않습니다 — 403을 참고하세요.

  • 409

    쓰는 동안 다른 무언가가 그 행을 바꿨습니다. 다시 읽고 다시 쓰세요.

  • 429

    요청이 너무 많습니다. 하루 예산을 다 썼거나 분당 버스트 상한에 걸렸습니다. 얼마나 기다릴지는 Retry-After가 알려주고, 402와 달리 이건 기다리면 풀립니다. 어느 상한이 거절했는지와 요금제별 수치는 제한 섹션을 참고하세요.

오류 형태

대부분의 오류는 같은 형태로 돌아옵니다: statusCode, message, 그리고 무엇이 잘못됐는지 이름 붙인 errors 객체입니다. 전부는 아닙니다. 401과 404는 본문 없이 돌아오므로 본문보다 상태 코드를 먼저 확인하세요.

예시

{
  "statusCode": 403,
  "message": "One or more errors occurred!",
  "errors": {
    "generalErrors": ["Transaction does not belong to the authenticated user"]
  }
}

요청 ID

모든 응답에는 fly-request-id 헤더가 담겨 있습니다. 특정 요청에 대해 지원팀에 문의할 때 이 값을 함께 알려주세요.

cURL

# Print the response headers, including fly-request-id; discard the body
curl -sS -D - -o /dev/null "https://forge.era.app/api/banking/transactions?page=1&pageSize=20" \
  -H "X-API-Key: fmk_your_key_here"

cURL (쓰기 호출)

# A write call: same header, plus a JSON body
curl -sS -D - -X PUT "https://forge.era.app/api/banking/transactions/utgr_your_transaction_id" \
  -H "X-API-Key: fmk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"categoryKey": "fcat_dining", "merchantName": "Corner Cafe"}'

흔한 오류

  • 같은 쓰기에서 필드를 설정하면서 동시에 지우기 — 400.

  • 일괄 업데이트에 100개를 넘는 id — 400, 아무것도 바뀌지 않습니다. 1개 미만도 마찬가지입니다.

  • 내 것이 아니거나 존재하지 않는 거래 — 403, 절대 404가 아닙니다. 그래서 응답은 그 id가 존재하는지는 절대 알려주지 않고, 단지 당신 것이 아니라는 것만 알려줍니다.

  • 다른 무언가가 먼저 그 행을 바꿨습니다 — 409.

제한

문서화된 열 개의 엔드포인트 중 두 개는 한 번의 호출로 요청할 수 있는 양에 상한이 있습니다. 나머지 여덟 개는 없습니다.

상한이 없다고 해서 무제한이란 뜻은 아닙니다: 키는 여전히 만료되고, 쓰기에는 여전히 필드 길이 제한이 있고, 카테고리 생성은 요금제 쿼터에 걸릴 수 있으며, 요금제에 따라 오래된 내역이 계속 숨겨질 수 있습니다. 이 중 어느 것도 속도 제한은 아닙니다 — 아래를 참고하세요.

  • 계좌, 잔액, 요약, 카테고리와 태그 목록, 카테고리 생성, 태그 생성, 그리고 단일 거래 쓰기는 호출당 물량 상한이 없습니다. 요청한 전체 세트, 또는 지정한 한 행 그대로를 돌려받습니다.

  • pageSize는 거부되지 않고 100으로 조정됩니다. 더 많이 요청해도 200과 함께 100개 행이 돌아옵니다 — 보낸 값을 믿지 말고 응답의 pagination.pageSize를 읽으세요.

  • 거래 일괄 쓰기는 id 100개로 제한되며, pageSize와 달리 조정이 아니라 거부됩니다: 101개를 보내면 400이 오고 아무것도 바뀌지 않습니다.

  • 키는 생성할 때 선택한 일정에 따라 만료됩니다 — 무료 플랜은 최대 90일, 유료 플랜은 365일입니다. 만료되지 않는 옵션은 없습니다.

  • 플랜에 따라 오래된 거래를 숨기는 히스토리 윈도우 하한이 적용될 수 있습니다. 거래 응답에는 하한이 적용됐는지와 어디에 걸렸는지를 알려주는 historyWindow 필드가 담겨 있습니다.

속도 제한

모든 요금제가 이 API를 호출할 수 있고, 모든 요금제가 계량됩니다. 계량되는 것은 당신이 키로 보내는 호출입니다. 하루 예산과 분당 버스트 상한이라는 두 상한이 동시에 적용되며, 둘 중 하나라도 넘기면 429가 돌아옵니다.

하루 예산은 키가 아니라 사용자에게 붙습니다. 계정의 모든 REST 키가 같은 하루 예산에서 차감되므로, 키를 하나 더 만든다고 호출 횟수가 늘지는 않습니다. MCP 도구 호출은 따로 집계됩니다. 한쪽을 써도 다른 쪽은 줄지 않습니다.

요금제별 하루·분당 요청 수
요금제하루분당
Basic

250

30

Organize

1,000

30

Automate

10,000

60

Operate

25,000

120

Era가 호출을 계량하면 응답에 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset이 실립니다. 셋 다 하루 예산을 설명합니다. 이 예산은 자정에 초기화되지 않고 24시간에 걸쳐 굴러갑니다. 가장 오래된 호출이 24시간이 지날 때마다 요청이 한 건씩 돌아옵니다. 분당 버스트 상한에는 헤더가 없으니, 표의 수치를 보고 직접 속도를 조절하세요. Remaining이 0보다 한참 높아도 버스트는 429로 돌아올 수 있습니다. Era가 사용량을 측정하지 못하면 호출을 그대로 처리하고 속도 제한 헤더를 보내지 않으니, 헤더가 없으면 오류가 아니라 측정값이 빠진 것으로 다루세요.

429가 알려주는 것

problem-details 본문입니다. detail 필드는 구조화된 필드가 아니라 일반 텍스트입니다. 걸린 상한, 그 상한이 허용하는 양, 다음 요청이 비는 시각, 그리고 상한을 올려주는 요금제(이미 최상위라면 그렇다는 사실)를 알려줍니다. 파싱하지 마세요. 코드에서 분기하려면 헤더를 읽으세요. Remaining이 0이면 하루 예산이, 0보다 크면 분당 버스트 상한이 거절한 것입니다.

429 응답

{
  "type": "https://httpstatuses.com/429",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "You've used up your daily budget of 250 requests. Your next request frees up at 2026-09-16T09:00:00Z. The Organize plan raises it."
}

429에는 Retry-After도 실립니다. 거절한 상한을 기준으로 잰 정수 초로, 분당 버스트 상한이면 최대 1분, 하루 예산이면 최대 24시간입니다. 거절된 호출은 아무것도 쓰지 않으므로 일찍 재시도해도 손해는 없지만, 다시 429가 돌아옵니다. Retry-After가 지나면 요청 한 건이 비는 것이지, 예산 전체가 돌아오는 게 아닙니다. 그 요청을 보낸 뒤 헤더나 다음 Retry-After를 읽으세요.

이 중 어느 것도 행방을 놓친 키를 지켜주지는 않습니다. 유출된 키는 사용자 본인과 똑같이 예산을 씁니다. 키가 의심스러우면 폐기하세요. 아래의 보안과 키 관리를 참고하세요.

공통 규칙

응답 필드는 camelCase입니다. 쿼리 파라미터는 대소문자를 가리지 않으니 여기서도 camelCase가 통합니다. 공개된 명세는 PascalCase로 적혀 있어서, 두 표기를 모두 보게 됩니다.

달력의 하루를 가리키는 필드는 YYYY-MM-DD입니다. 어느 한 시점을 가리키는 필드는 오프셋이 붙은 ISO 8601입니다.

페이지 크기는 거절되는 것이 아니라 잘려 맞춰집니다. pageSize에 500을 넣어도 돌아오는 것은 100건과 200이지 오류가 아닙니다. 그러니 보낸 값을 믿지 말고 pagination.pageSize를 다시 읽으세요.

응답에는 이 페이지에 적히지 않은 필드가 담길 수 있습니다. 모르는 필드는 오류로 만들지 말고 그냥 넘기세요. 그래야 API가 자라도 당신의 클라이언트가 계속 동작합니다.

REST는 평범한 HTTP라 호출하는 데 SDK가 필요 없습니다. HTTP 클라이언트가 있는 언어면 어떤 것이든 됩니다. 설치할 것은 없습니다.

버전과 변경

여기 문서로 적힌 것은 모두 이 정책의 대상입니다.

경로에 버전 번호가 없고 버전 헤더도 없습니다. 엔드포인트마다 살아 있는 버전은 하나이고, 그것이 여기 적힌 버전입니다.

예고 없이 바꿀 수 있는 것

위의 규약을 따르는 클라이언트를 깨뜨리는 것은 하나도 없습니다.

  • 엔드포인트를 추가하거나, 이미 있는 엔드포인트에 작업을 추가한다.

  • 응답에 필드를 추가한다.

  • 선택적 파라미터를 추가한다. 넣지 않으면 달라지는 것이 없다.

  • 정해진 값 집합에 값을 추가한다. 상태나 종류 같은 것.

  • 응답 헤더를 추가한다.

예고 없이 바꾸지 않는 것

어느 것이든 잘 돌던 클라이언트를 깨뜨릴 수 있습니다.

  • 엔드포인트를 없애거나, 경로나 메서드를 바꾼다.

  • 응답 필드를 없애거나 이름을 바꾼다.

  • 필드의 타입이나 의미를 바꾼다.

  • 지금은 선택인 파라미터를 필수로 만든다.

  • 지금은 받아 주는 입력을 거부한다.

  • 엔드포인트에 필요한 범위를 바꾼다.

이런 변경을 하기 전에는 최소 90일 앞서 변경 이력에서 알리고, 무엇을 바꿔야 하는지 안내합니다. 지금 동작하는 것은 그때까지 계속 동작합니다.

변경은 변경 이력에서 알립니다. 링크는 아래 '변경 이력' 섹션에 있습니다. 이메일이나 피드는 아직 없으니 API 관련 작업을 계획할 때 그곳을 확인하세요.

API가 베타인 동안 문서로 적힌 범위는 계속 넓어집니다. 이미 여기 있는 것은 예고 없이 깨지지 않습니다.

변경 이력

Era API를 포함한 Era Developer Platform의 업데이트를 최신순으로 정리했습니다. 위의 정책은 무엇을 얼마나 앞서 예고하는지를 정하고, 변경 이력은 그 예고가 실리는 곳입니다.

변경 이력 열기

보안과 키 관리

에이전트를 승인하면 키가 만들어집니다

OAuth로 에이전트를 승인하면 Era가 그 에이전트용 API 키를 만듭니다. 직접 만든 키들과 같은 대시보드 목록에, 클라이언트 이름을 바탕으로 Era가 지은 이름으로 나타납니다.

이름이 붙는 방식

Auto -- Claude

그 화면에서 승인한 범위만 정확히 지니고, 그 밖의 것은 없습니다. 대시보드에서 폐기하면, 다시 승인할 때까지 에이전트는 새 액세스 권한을 받을 수 없습니다. 이미 가진 토큰은 만료될 때까지, 최대 한 시간 동안 계속 작동합니다.

쓰기는 활동 기록에 남고, 읽기는 남지 않습니다

키를 만들고 폐기하는 일은 둘 다 활동 기록에 남고, 에이전트가 MCP로 하는 모든 도구 호출도 남습니다. REST 쓰기도 남습니다 — 태그를 만들었다, 거래를 수정했다처럼 그 쓰기가 만든 변경으로 기록됩니다. REST 읽기는 항목을 전혀 만들지 않습니다. 이 항목들은 어느 요금제에서나 기록되지만, 기록 전체를 읽으려면 Organize 이상이 필요합니다. 그 아래에서는 가장 최근 항목만 보입니다. 쓰기라도 REST에는 요청 단위 기록이 없습니다. 남는 것은 변경이지 호출이 아니고, 그 변경은 그것을 만든 키가 아니라 계정에 귀속됩니다.

어떤 키가 미덥지 않다면 폐기하세요. 직접 만든 키는 다음 요청부터 REST와 MCP에서 작동하지 않습니다. 에이전트의 키는 즉시 새 액세스 권한을 받지 못하고, 이미 가진 토큰도 한 시간 이내에 만료됩니다. 새로 만드는 데는 1분이면 됩니다.

키를 믿고 쓰기 전에 알아둘 것들.
항목의미
범위는 성깁니다

banking:read는 이 페이지의 여섯 개 읽기보다 훨씬 넓은 범위를 읽습니다. 같은 범위가 계정의 나머지 읽기, 곧 잔액·보유 자산·연결·지출까지 덮습니다. 범위는 이 하나뿐이고, 이보다 좁은 선택지는 없습니다. 쓰기 범위도 읽기 범위와 마찬가지로 선택지에 있습니다. 어떤 키든 당신의 계정으로서 동작하니, 비밀번호처럼 다루세요. 계정의 일부가 아니라 계정 전체로서 동작합니다. banking:write는 카테고리, 태그, 거래 메타데이터를 바꿀 수 있고, 수동 계좌와 잔액을 관리하며, 금융기관을 연결하거나 해제할 수도 있습니다 — 이 페이지의 어떤 범위도 당신의 은행 계좌 사이에서 돈을 옮길 수 없습니다.

범위는 갱신되지 않습니다

키의 범위는 만들 때 정해지고 이후로 바뀌지 않습니다. 어떤 범위가 덮고 있지만 아직 열리지 않은 것에서 이 점이 중요합니다. 오늘 social:write를 부여하면, 공유 뷰가 열리는 날에도 그 키는 그것을 그대로 지니고 있습니다. 지금 쓰는 것만 부여하고, 언젠가 쓸지도 모르는 것은 두세요.

승인이 필요 없습니다

당신은 이미 자신의 계정에 로그인되어 있으므로, 키를 만드는 데 다른 누구의 승인도 필요 없습니다 — 심사도 대기열도 없고, Era의 누구도 요청을 승인하지 않습니다. 만드는 순간 활동 기록에 남으니, 만든 적 없는 키는 쉽게 알아챌 수 있습니다.

은행 로그인에는 닿지 않습니다

키는 은행 로그인에 닿지 못합니다. Era가 그것을 아예 갖고 있지 않기 때문입니다. 로그인 정보는 데이터 제공자가 운영하는 연결 화면에서 입력하지, Era 화면에서 입력하지 않습니다. 이후 Era가 보관하는 것은 연결마다 하나씩 있는 액세스 토큰뿐이며, AES-256으로 암호화되어 저장되고, 기관 연결을 끊으면 버릴 수 있습니다.

키는 해시만 저장됩니다

키는 256비트의 무작위 데이터이고, 저장 전에 SHA-256으로 해시됩니다. 우리가 보관하는 것은 해시이지 키가 아닙니다. 잃어버리면 폐기하고 새로 만드세요.

핵심 리소스

계좌

GET/banking/accounts

필요한 범위

banking:read

연결된 모든 기관에 걸쳐, 볼 수 있는 계좌를 전부 돌려줍니다. 빠진 계좌가 몇 개인지도 함께 옵니다. 계좌마다 잔액 엔드포인트가 경로로 받는 값인 accountGroupKey와, 그 계좌가 속한 connectionId가 함께 담겨 있으니 먼저 이 호출부터 하시면 됩니다. connectionId로 한 연결만 좁힐 수 있고, includeExcluded로 숨겨 둔 계좌까지 넣을 수 있습니다.

쿼리 파라미터
connectionId선택

목록을 한 연결의 계좌로만 좁힙니다.

includeExcluded선택

등급 제외 계좌와 숨긴 계좌도 포함하되, 잔액은 흐려서 보여줍니다. 기본값은 false입니다.

응답 · 200

{
  "accounts": [
    {
      "accountGroupKey": "uagr_7f3c9a21",
      "connectionId": "ucon_4b19e02c",
      "name": "Everyday Checking",
      "currentBalance": 4820.16,
      "supportsTransactions": true,

    }
  ],
  "excludedAccountCount": 1
}

숨겨 둔 계좌나 요금제에서 제외된 계좌에서는 잔액 필드가 0이 아니라 null로 옵니다. null은 비었다는 뜻이 아니라 알려 주지 않는다는 뜻입니다. supportsTransactions의 null도 같은 뜻으로, Era가 말할 수 없다는 것이지 답이 아니라는 뜻은 결코 아닙니다.

계좌 잔액

GET/banking/accounts/{accountId}/balance

필요한 범위

banking:read

One account's balance, with the credit fields filled in when the account is a liability. The path takes that account's accountGroupKey — the same value /banking/accounts returns for it. The key is not checked for shape before the lookup, so a malformed key and an unknown one answer the same way.

응답 · 200

{
  "accountGroupKey": "uagr_7f3c9a21",
  "currentBalance": 4820.16,
  "availableBalance": 4712.03,
  "creditLimit": null,
  "currencyCode": "USD",
  "availableCredit": null,
  "asOf": "2026-08-11T09:32:00Z",
  "visibility": null
}

숨긴 계좌도, 연결이 끊긴 계좌도 여전히 200으로 답합니다. 대신 잔액 필드가 null입니다. 404는 그 계좌가 정말로 없거나, 키가 키 형태가 아니었다는 뜻입니다. 여기서는 visibility 필드를 눈여겨보세요. 계좌가 보일 때는 null이고, 보이지 않을 때는 tier_excluded 같은 문자열이 들어갑니다.

계좌 요약

GET/banking/accounts/summary

필요한 범위

banking:read

볼 수 있는 계좌들의 합계입니다. totalAssets, totalLiabilities, 그리고 앞의 것에서 뒤의 것을 뺀 netWorthHint가 들어 있습니다. 파라미터는 없습니다.

응답 · 200

{
  "userId": "7d1c0b93a8e24f60",
  "accounts": [],
  "totalVisibleCount": 6,
  "totalHiddenCount": 2,
  "totalAssets": 48210.75,
  "totalLiabilities": 9327.40,
  "netWorthHint": 38883.35,
  "computedAt": "2026-08-11T09:32:00Z"
}

netWorthHint가 세는 것은 이 응답에 담긴 계좌뿐이니, 무엇이 빠졌는지는 totalHiddenCount가 알려 줍니다. 확정된 순자산이 아니라 출발점이 되는 숫자로 다루세요.

거래

GET/banking/transactions

필요한 범위

banking:read

거래를 한 페이지씩, 페이지 수 정보와 함께 감싸서 돌려줍니다. page와 pageSize(최대 100)를 받고, 계좌·기간·적용된 규칙·부여된 태그로 선택적 필터를 걸 수 있습니다.

쿼리 파라미터
accountId선택

한 계좌의 거래로만 좁힙니다. 그 계좌의 accountGroupKey로 지정합니다.

fromDate선택

이 날짜 이후 거래만 반환합니다.

toDate선택

이 날짜 이전 거래만 반환합니다.

page선택

페이지 번호, 1부터 시작. 기본값은 1입니다.

pageSize선택

페이지당 행 수. 기본값은 50이며, 100까지 제한됩니다.

sortBy선택

정렬 기준 필드: transactionDate, amount, description, category, merchantName 중 하나.

sortDirection선택

asc 또는 desc. 기본값은 내림차순입니다.

categoryKeys선택

Only transactions in these categories, by their fcat_ keys. Takes a list, not a single key, and a transaction matches if its effective category is any one of them. Send the literal "uncategorized" to select the transactions that have no category at all.

search선택

가맹점, 설명, 카테고리, 계좌 이름, 금액에 걸친 전체 텍스트 검색입니다.

ruleIds선택

자동화 규칙이 적용된 거래만, 규칙의 키로 지정합니다.

tagKeys선택

이 태그 중 하나가 붙은 거래만 반환합니다.

reviewStatuses선택

needs_review, reviewed, flagged 중 하나입니다. 여러 개를 지정할 수 있으며, 검토 상태가 그중 하나인 거래가 반환됩니다.

includeChildren선택

With a category filter set, also include transactions in the subcategories of every key you passed. Defaults to false.

includePending선택

지난 7일간의 보류 중 거래도 함께 반환하며, isPending으로 표시됩니다. 기본값은 false입니다. 보류 중 행은 읽기 전용입니다.

응답 · 200

{
  "transactions": [],
  "pagination": {
    "currentPage": 1,
    "pageSize": 20,
    "totalItems": 412,
    "totalPages": 21
  },
  "historyWindowApplied": true,
  "historyWindowFloorDate": "2026-06-28",
  "historyWindowHiddenCount": 137,
  "historyWindowEarliestDate": "2024-03-02",
  "historyWindowDegraded": false
}

요금제에 따라 히스토리 윈도 경계가 적용되어, 그보다 오래된 거래는 가려집니다. 응답에 historyWindow 필드들이 담기는 이유가 이것입니다. historyWindowApplied는 경계가 실제로 무언가를 가렸음을, historyWindowFloorDate는 그 경계가 어디인지를, historyWindowHiddenCount는 뒤에 몇 건이 있는지를, historyWindowEarliestDate는 히스토리가 실제로 어디까지 거슬러 가는지를 알려 줍니다. 이것이 없으면 짧은 결과는 더 오래된 거래가 없는 계정과 구분되지 않습니다. 이 가운데 둘은 코드를 다르게 쓰게 만듭니다. historyWindowHiddenCount는 경계가 적용된 경우에도 null일 수 있으니, null은 0이 아니라 알 수 없음이라는 뜻으로 읽으세요. 그리고 historyWindowDegraded가 true이면 그 조회에서 Era가 요금제를 확인하지 못한 것이므로, 경계 날짜는 사실이 아니라 추정입니다. 요금제가 확인된 유료 조회에서는 경계가 적용되지 않고 historyWindowApplied는 false로 돌아옵니다.

요금제는 하루에 쓸 수 있는 요청 수도 정하고, 이 API는 그것을 실제로 적용합니다. 요금제별 수치, 모든 응답에 실리는 헤더, 그리고 429가 알려주는 내용은 모두 제한 섹션에 있습니다.

거래 하나 바꾸기

거래에서 직접 재지정할 수 있는 것은 네 가지입니다: 카테고리, 가맹점 이름, 직접 남긴 메모, 그리고 검토 상태. 바꾸려는 것만 보내세요 — 빼놓은 것은 그대로 남습니다. 경로의 id는 그 거래의 utgr_ 키입니다. 데이터를 바꾸므로 banking:read가 아니라 banking:write가 필요합니다.

PUT/banking/transactions/{id}

필요한 범위

banking:write
요청 본문
categoryKey선택

지정할 카테고리의 fcat_ 키입니다. 빼면 거래는 지금 가진 카테고리를 그대로 유지합니다.

merchantName선택

직접 정한 가맹점 이름, 최대 1000자. 빼면 지금 이름이 그대로 유지됩니다.

description선택

이 거래에 대한 직접 남긴 메모, 최대 5000자. 빼면 지금 메모가 그대로 유지됩니다.

clearCategory선택

카테고리 재지정을 지워서, Era 자체 분류가 다시 적용되게 합니다. 기본값은 false입니다.

clearMerchantName선택

가맹점 이름 재지정을 지워서, 은행이 보낸 이름이 다시 돌아오게 합니다. 기본값은 false입니다.

clearDescription선택

메모 재지정을 지워서, 은행이 보낸 설명이 다시 돌아오게 합니다. 기본값은 false입니다.

reviewStatus선택

needs_review, reviewed, flagged 중 하나로 표시합니다.

clearReviewStatus선택

검토 상태 재지정을 지웁니다. 기본값은 false입니다.

응답 · 200

{
  "transaction": {}
}

업데이트된 거래 전체가 응답으로 돌아오는데, 위 목록이 돌려주는 것과 같은 형태입니다 — 아직 계속 바뀌는 큰 객체라 여기서는 다시 적지 않았습니다. 같은 필드를 지정하면서 동시에 지우면 400이 돌아옵니다. 당신 것이 아니거나 아예 존재하지 않는 거래라면 403이 돌아옵니다 — API는 이 둘을 구분해 알려주지 않습니다. 그리고 쓰는 동안 다른 무언가가 같은 행을 바꿨다면 409가 돌아옵니다: 다시 읽고 다시 보내세요.

한 번에 최대 100개 바꾸기

같은 네 가지 재지정을, 한 번의 호출로 거래 목록 전체에 적용합니다. 목록의 모든 id가 같은 변경을 받습니다 — 거래마다 다르게 적용할 수는 없습니다. 데이터를 바꾸므로 banking:read가 아니라 banking:write가 필요합니다.

PUT/banking/transactions/bulk

필요한 범위

banking:write
요청 본문
transactionIds

바꿀 거래들의 utgr_ 키. 최소 하나, 최대 100개까지입니다. 100개를 넘으면 잘라내지 않고 아예 거절합니다 — 위의 pageSize와 달리, 400이 돌아오고 아무것도 바뀌지 않습니다.

categoryKey선택

지정할 카테고리의 fcat_ 키입니다. 빼면 거래는 지금 가진 카테고리를 그대로 유지합니다.

merchantName선택

직접 정한 가맹점 이름, 최대 1000자. 빼면 지금 이름이 그대로 유지됩니다.

description선택

이 거래에 대한 직접 남긴 메모, 최대 5000자. 빼면 지금 메모가 그대로 유지됩니다.

clearCategory선택

카테고리 재지정을 지워서, Era 자체 분류가 다시 적용되게 합니다. 기본값은 false입니다.

clearMerchantName선택

가맹점 이름 재지정을 지워서, 은행이 보낸 이름이 다시 돌아오게 합니다. 기본값은 false입니다.

clearDescription선택

메모 재지정을 지워서, 은행이 보낸 설명이 다시 돌아오게 합니다. 기본값은 false입니다.

reviewStatus선택

needs_review, reviewed, flagged 중 하나로 표시합니다.

clearReviewStatus선택

검토 상태 재지정을 지웁니다. 기본값은 false입니다.

응답 · 200

{
  "transactions": []
}

업데이트된 거래들이 응답으로 돌아오는데, 위 목록이 돌려주는 것과 같은 형태입니다. 같은 필드를 지정하면서 동시에 지우면 400이 돌아오고, 빈 목록을 보내도 마찬가지입니다. 당신 것이 아니거나 아예 존재하지 않는 거래가 목록에 하나라도 있다면, 호출 전체에 403이 돌아옵니다 — 아무것도 바뀌지 않습니다. 쓰는 동안 다른 무언가가 그 행들 중 하나를 바꿨다면 409가 돌아옵니다: 다시 읽고 다시 보내세요.

카테고리

GET/banking/categories

필요한 범위

banking:read

카테고리 체계 전체입니다. 카테고리 묶음마다 하위 카테고리가 중첩되어 들어 있습니다. 이 체계는 공용이며 계좌별이 아닙니다.

응답 · 200

{
  "packs": [
    {
      "packSlug": "default",
      "packName": "Era default categories",
      "isDefault": true,
      "categories": [
        {
          "projectionKey": "fcat_food_dining",
          "categoryName": "Food & dining",
          "isTopLevel": true,
          "children": []
        }
      ]
    }
  ],
  "meterLimit": 25,
  "canCreateCustomCategories": true
}

카테고리 추가하기

기존 상위 카테고리 아래에 만드는 사용자 정의 카테고리입니다. 데이터를 바꾸므로 banking:read가 아니라 banking:write가 필요합니다.

POST

필요한 범위

banking:write
요청 본문
slug

URL에 쓸 수 있는 식별자 — 소문자, 숫자, 하이픈만, 2~50자.

parentCategoryKey

이 카테고리가 속할 상위 카테고리의 fcat_ 키.

name

표시 이름.

description선택

선택적 설명.

iconName선택

선택적 아이콘 이름.

spendingType선택

선택적 지출 분류.

displayOrder선택

형제 카테고리들 사이의 선택적 정렬 위치.

assignmentEligibility선택

이 카테고리를 어떤 거래에 지정할 수 있는지에 대한 선택적 규칙.

sourceSystemKeys선택

앞으로 이곳으로 라우팅할, 기존 카테고리 키들의 선택적 목록.

applyRetroactively선택

true면 과거 거래도 새 라우팅 기준으로 다시 평가합니다. 기본값은 false입니다.

응답 · 201

{
  "categoryKey": "fcat_side_hustle_9f2a",
  "overlayProjectionKey": "fcov_9f2a1c",
  "action": "created",
  "isQuotaExceeded": false,
  "createdMappingRuleKeys": [],

}

응답에는 retroactiveAffectedCount, mergeSourcesHiddenCount, mergeSourcesTotalCount, meterGate도 담겨 있습니다 — 이 호출이 카테고리 병합, 한도 제한 생성과 공유하는 필드들로, 여기서는 표시하지 않았습니다.

태그

GET/banking/tags

필요한 범위

banking:read

계정의 모든 태그를 한 목록으로 돌려줍니다. 페이지 나눔은 없습니다. 한 번의 응답이 전부를 돌려줍니다.

쿼리 파라미터
tagType선택

태그 출처로 필터링합니다: user, system, auto 중 하나.

includeDeleted선택

삭제된 태그도 포함합니다. 기본값은 false입니다.

응답 · 200

{
  "tags": [
    {
      "tagKey": "utag_9c2f01ab",
      "name": "business-expense",
      "displayName": "Business expense",
      "tagType": "user",
      "color": "#6DC6BA",
      "transactionCount": 42
    }
  ]
}

태그 만들기

A new tag, canonicalized to lowercase. Mutating, so it needs banking:write rather than banking:read. System tags cannot be created through the API; user and auto tags can.

POST

필요한 범위

banking:write
요청 본문
name

태그의 표준 이름.

displayName선택

선택적 표시 이름. 기본값은 표준 이름입니다.

tagType선택

user or auto. Defaults to user. system is refused — it is reserved for tags Era creates itself.

color선택

표시용 선택적 16진 색상.

icon선택

선택적 아이콘 이름.

응답 · 201

{
  "tag": {
    "tagKey": "utag_9c2f01ab",
    "name": "business-expense",
    "displayName": "Business expense",
    "tagType": "user",
    "version": 1,
    "createdAt": "2026-08-26T09:15:00Z"
  }
}