본문으로 건너뛰기

Era API

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

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

아직 베타입니다

이 엔드포인트들은 오늘 기준으로 동작하지만, 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
}

사용 가능한 API

Era API에는 다음 API가 포함되어 있습니다:

인증

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

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

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

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

응답 헤더

요청 ID는 모든 응답에 들어갑니다. 속도 제한 헤더는 Era가 하루 예산에 대해 계량한 호출에 붙습니다. 429에는 그 하루 예산이 거절했을 때만 붙고, 분당 버스트 상한 때문에 돌아온 429에는 Retry-After만 붙습니다. 당분간 하루 예산은 무료 요금제에만 있습니다. Era가 사용량을 측정하지 못하면 호출을 그대로 처리하고 이 헤더는 하나도 보내지 않습니다.

응답 헤더
fly-request-id
요청을 고유하게 식별하는 ID입니다. 특정 요청에 대해 지원팀에 문의할 때 이 값을 함께 알려주세요. 참고: 요청 ID
X-RateLimit-Limit
요금제의 하루 예산입니다. 하루 예산이 있는 요금제에서만 보내며, 분당 버스트 상한 때문에 돌아온 429에는 보내지 않습니다.
X-RateLimit-Remaining
하루 예산에서 남은 양입니다. 0 아래로 내려가지 않습니다. 하루 예산이 있는 요금제에서만 보내며, 분당 버스트 상한 때문에 돌아온 429에는 보내지 않습니다.
X-RateLimit-Reset
하루 예산에서 다음 요청 한 건이 비는 시각을 Unix 타임스탬프 초로 알려줍니다. 예산 전체가 다시 차는 시각이 아닙니다. 예산은 굴러가므로 요청은 한 건씩 돌아옵니다. 하루 예산이 있는 요금제에서만 보내며, 분당 버스트 상한 때문에 돌아온 429에는 보내지 않습니다. 분당 버스트 상한에는 전용 헤더가 없습니다. 참고: 제한
Retry-After429에만
요청을 거절한 상한을 기준으로, 다시 시도하기 전에 기다릴 초입니다. X-RateLimit-*도 실린 429는 하루 예산이, 없는 429는 분당 버스트 상한이 거절한 것입니다. 참고: 제한

오류

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

  • 400

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

  • 401

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

  • 402

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

  • 403

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

  • 404

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

  • 409

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

  • 429

    요청이 너무 많습니다. 분당 버스트 상한에 걸렸거나, 무료 요금제에서 하루 예산을 다 썼습니다. X-RateLimit-* 헤더가 실린 429는 하루 예산, 없는 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가 적용하는 속도 제한은 두 가지입니다. 모든 요금제에는 버스트 상한이 있습니다. 직전 1분 동안의 요청 수 상한입니다. 무료 요금제에는 하루 예산도 있습니다. 직전 24시간 동안의 요청 수 상한입니다. 요청은 보낸 지 1분이 지나면 버스트 상한 계산에서, 하루가 지나면 하루 예산 계산에서 빠집니다. 당분간 유료 요금제에는 하루 예산이 없으므로, 유료 요금제의 상한은 버스트 상한뿐입니다. 둘 중 하나라도 넘기면 호출은 429로 돌아옵니다.

상한은 키가 아니라 계정에 속합니다. 만든 모든 REST 키가 같은 버스트 상한을, 무료 요금제에서는 같은 하루 예산도 함께 쓰므로 키를 하나 더 만들어도 호출이 늘지 않습니다. MCP 도구 호출은 따로 집계되므로, REST 호출과 MCP 호출이 서로의 상한을 쓰는 일은 없습니다.

요금제별 속도 제한
요금제하루 예산버스트 상한
Basic하루 100건분당 10건
Organize없음분당 30건
Automate없음분당 60건
Optimize없음분당 60건
Operate없음분당 120건

당분간 유료 요금제에는 하루 예산이 없습니다.

유료 요금제에는 공정 사용도 적용됩니다. 이는 카운터가 아니라 정책이므로, API가 이를 이유로 호출을 거부하는 일은 없습니다. API는 본인의 금융 데이터를 다루는 스크립트, 대시보드, 연동을 위한 것이며, 한 사람이 쓰기에 알맞은 양을 전제로 합니다. 사용량이 그 범위를 넘는다고 판단되더라도, 먼저 연락드리지 않고 계정을 차단하지 않습니다. 요금 안내에서는 이를 ‘당분간 무제한(공정 사용)’이라고 부릅니다.

무료 요금제에서는 처리된 모든 응답이 응답 헤더에서 설명하는 X-RateLimit-* 헤더로 하루 예산을 알려줍니다. 유료 요금제의 응답에는 이 헤더가 하나도 없습니다. 어느 요금제에서도 버스트 상한을 알려주는 헤더는 없으므로, 표를 기준으로 속도를 조절하세요. 무료 요금제에서는 버스트가 429로 돌아오기 직전에도 Remaining이 0보다 훨씬 클 수 있습니다. Era가 사용량을 측정하지 못하면 헤더 없이 호출을 처리하므로, 무료 요금제에서 헤더가 없는 응답은 오류가 아니라 집계를 알 수 없는 상태로 보세요.

429가 알려주는 것

어떤 상한에 걸렸는지 알려줍니다. X-RateLimit-* 헤더가 실린 429는 하루 예산, 없는 429는 버스트 상한 때문입니다. 이는 모든 요금제에서 같습니다. 본문은 problem-details 형식이며, detail 필드에는 걸린 상한, 그 상한이 허용하는 양, 다음 요청이 비는 시각, 그리고 상한을 올리거나 없애주는 요금제(이미 최상위라면 그렇다는 사실)가 적혀 있습니다. 사람이 읽도록 쓴 글이므로, 파싱하지 말고 헤더를 읽으세요.

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

모든 429에는 Retry-After도 실립니다. 초 단위의 정수이며, 1보다 작지 않습니다. 버스트 상한이면 최대 1분, 무료 요금제의 하루 예산이면 최대 24시간입니다. 거부된 호출은 어느 상한에도 포함되지 않지만, 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

연결된 모든 기관에 걸쳐, 볼 수 있는 계좌를 전부 돌려줍니다. 빠진 계좌가 몇 개인지도 함께 옵니다. 그 수가 excludedAccountCount이고, 요금제의 계좌 한도 때문에 빠진 tierExcludedAccountCount와 직접 숨긴 userExcludedAccountCount로 나뉩니다. accountLimit은 모든 연결을 합쳐 요금제가 한 번에 보여 주는 계좌 수입니다. accountLimitLift는 숨기지 않은 계좌가 모두 들어가는 가장 저렴한 요금제의 이름이고, 요금제 때문에 빠진 계좌가 없으면 null입니다. 계좌마다 잔액 엔드포인트가 경로로 받는 값인 accountGroupKey와, 그 계좌가 속한 connectionId가 함께 담겨 있으니 먼저 이 호출부터 하시면 됩니다. connectionId로 한 연결만 좁힐 수 있고(개수는 함께 좁혀지지만 accountLimit과 accountLimitLift는 그대로입니다), includeExcluded로 요금제 때문에 빠진 계좌와 숨겨 둔 계좌까지 넣을 수 있습니다.

쿼리 파라미터
connectionId선택
목록을 한 연결의 계좌로만 좁힙니다.
includeExcluded선택
요금제 때문에 빠진 계좌와 숨긴 계좌도 포함하되, 잔액은 알려 주지 않습니다. 어느 쪽인지는 각 행의 visibility가 알려 줍니다. tierExcluded 또는 userExcluded이고, 나머지는 visible입니다. 잔액 엔드포인트는 이 값을 다르게 표기하니, 두 곳에 같은 파서를 쓰지 마세요. 이 값이 true여도 excludedAccountCount는 오고, 그 계좌들은 이미 목록에 들어 있으니 둘을 더하지 마세요. 기본값은 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가 말할 수 없다는 것이지 답이 아니라는 뜻은 결코 아닙니다. 요금제 필드도 마찬가지입니다. 그 호출에서 Era가 요금제를 읽지 못했다면 tierExcludedAccountCount, userExcludedAccountCount, accountLimit, accountLimitLift가 모두 null로 옵니다. 계좌 한도가 없는 요금제에서는 accountLimit도 null이고, 더 여유 있는 요금제가 없거나 요금제 때문에 빠진 계좌가 없을 때는 accountLimitLift가 null입니다.

계좌 잔액

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, 직접 숨겼을 때는 user_excluded, 연결이 끊겼을 때는 connection_severed가 들어갑니다. tier_excluded일 때는 accountLimit이 요금제의 한도이고, accountLimitLift는 이 계좌를 포함해 숨기지 않은 계좌가 모두 들어가는 가장 저렴한 요금제의 이름입니다. 그 밖의 상태에서는 accountLimitLift가 null이고, connection_severed일 때는 accountLimit도 null입니다.

계좌 요약

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가 알려 줍니다. 그중 tierExcludedAccountCount개는 요금제의 계좌 한도 때문에 빠졌고, userExcludedAccountCount개는 직접 숨긴 계좌입니다. accountLimitLift는 앞의 계좌들을 되돌리는 가장 저렴한 요금제의 이름이고, 그런 계좌가 없으면 null입니다. netWorthHint는 확정된 순자산이 아니라 출발점이 되는 숫자로 다루세요.

거래

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로 돌아옵니다. 요금제의 계좌 한도 때문에 빠지는 거래도 있습니다. tierExcludedAccountCount는 이 조회에서 한도 때문에 빠진 계좌 수이고, userExcludedAccountCount는 직접 숨긴 계좌 수입니다. 계좌로 필터링했다면 둘 다 그 계좌만 셉니다. 그 호출에서 Era가 요금제를 읽지 못했다면 둘 다 null입니다.

긴 내역을 페이지별로 넘기면 요청이 소모됩니다. 요금제는 호출 속도를 제한하고, 무료 요금제에서는 하루에 쓸 수 있는 호출 수도 제한합니다. 요금제별 수치, 속도 제한 헤더, 그리고 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도 담겨 있습니다 — 이 호출이 카테고리 병합과 공유하는 필드들로, 여기서는 표시하지 않았습니다. 여기에 isQuotaExceeded, quotaExceededMessage, meterGate도 오는데, 생성된 카테고리에서는 항상 false, null, null입니다. 요금제 한도 때문에 생성이 거절되면 대신 402가 오고, 이 필드들은 하나도 담기지 않습니다. 본문은 statusCode, message, errors.generalErrors이며, errors.generalErrors의 유일한 항목이 어느 한도에 걸렸는지 알려 줍니다.

태그

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"
  }
}

Era Financial Advisors LLC는 SEC 등록 투자자문사입니다(CRD #334404). 등록이 특정 수준의 기술이나 교육을 의미하지는 않습니다. 투자자문 서비스는 재량형이며 AI 지원 방식으로 제공되며, 개인 맞춤 재무 상담을 대체하지 않습니다. 중개 및 수탁 서비스는 별도 법인이자 FINRA/SIPC 회원인 Alpaca Securities LLC가 제공합니다. Era Thesis 및 Era Agency 계좌는 현재 미국 거주자만 개설할 수 있습니다. Era Context는 미국, 영국, 캐나다, 프랑스, 독일, 스페인을 비롯해 총 40개국 이상의 계좌를 연결합니다. 본 웹사이트의 어떠한 내용도 증권의 매수 또는 매도를 권유하는 것이 아닙니다. 과거 실적이 미래 수익을 보장하지 않습니다. 투자 전 당사의 Form ADV 및 Form CRS를 확인하시기 바랍니다.

era© 2026 Tinwell Labs Inc. DBA Era