NetSuite REST 커넥터
API 문서
섹션 제목: “API 문서”NetSuite REST API Browser에는 레코드 엔드포인트가 문서화되어 있고, SuiteQL 참조에는 이 커넥터가 테이블 형식 데이터를 가져오는 데 사용하는 쿼리 언어가 문서화되어 있습니다.
인증 방식
섹션 제목: “인증 방식”이 커넥터는 PS256 JWT 클라이언트 어서션을 사용하는 OAuth 2.0 클라이언트 자격 증명으로 로그인합니다. 대화형 로그인이나 새로 고침 토큰은 없습니다. RSA 키 쌍을 생성하고 공개 인증서를 NetSuite에 업로드한 다음, 대응하는 개인 키와 ID 세 개를 PlaidCloud에 제공합니다. 가져올 때마다 PlaidCloud는 수명이 짧은 어서션을 만들어 서명하고, 이를 액세스 토큰으로 교환한 다음 REST API를 호출합니다.
NetSuite 측 설정
섹션 제목: “NetSuite 측 설정”PlaidCloud 연결을 만들기 전에 NetSuite에서 다음을 수행하십시오. 관리자 권한이 필요하며 전체 작업의 핵심 경로에 해당합니다.
1. 기능 사용 설정
섹션 제목: “1. 기능 사용 설정”Setup > Company > Enable Features > SuiteCloud에서 OAuth 2.0과 SuiteTalk (SOAP and REST Web Services) 를 사용 설정합니다.
2. RSA 키 쌍 만들기
섹션 제목: “2. RSA 키 쌍 만들기”PS256을 지원하는 다이제스트로 2048비트 이상의 RSA 키 쌍을 생성합니다. 예를 들어 OpenSSL을 사용하면 다음과 같습니다.
openssl genrsa -out plaidcloud_netsuite.pem 2048openssl rsa -in plaidcloud_netsuite.pem -pubout -out plaidcloud_netsuite_public.pem개인 키(plaidcloud_netsuite.pem)는 비밀로 유지하십시오. 이 키는 PlaidCloud에 입력하며 NetSuite에는 절대 입력하지 않습니다.
3. 공개 인증서 업로드 → 인증서 ID
섹션 제목: “3. 공개 인증서 업로드 → 인증서 ID”Setup > Integration > OAuth 2.0 Client Credentials (M2M) Setup에서 공개 인증서를 통합, 엔터티, 역할에 매핑합니다. NetSuite는 업로드한 공개 키에 대한 인증서 ID를 반환합니다. 이것이 JWT kid이며 시크릿이 아닙니다. 기록해 두십시오.
4. 통합 레코드 만들기 → 클라이언트 ID
섹션 제목: “4. 통합 레코드 만들기 → 클라이언트 ID”Setup > Integration > Manage Integrations > New에서 OAuth 2.0을 사용 설정하고 Client Credentials 권한 부여를 선택하여 통합을 만듭니다. NetSuite가 클라이언트 ID(컨슈머 키)를 발급합니다. 기록해 두십시오. 클라이언트 자격 증명 + 어서션 흐름에는 클라이언트 시크릿이 없습니다.
5. 역할 및 권한
섹션 제목: “5. 역할 및 권한”M2M 매핑에 사용하는 역할에 읽으려는 항목을 포괄하는 권한 집합을 할당합니다.
- REST Web Services (Setup) — 모든 REST 호출에 필요합니다.
- SuiteAnalytics Workbook — SuiteQL이 분석/워크북 데이터를 다루는 경우 필요합니다.
- Log in using OAuth 2.0 Access Tokens — 토큰 교환에 필요합니다.
- 쿼리가 읽는 모든 레코드 유형(트랜잭션, 계정, 엔터티 등)에 대한 레코드 수준 보기 권한.
6. 계정 ID
섹션 제목: “6. 계정 ID”Setup > Company > Company Information(Account ID 필드)에서 계정 ID를 확인합니다. 이 값으로 API 호스트가 결정됩니다.
| 환경 | 계정 ID 형식 | API 호스트 |
|---|---|---|
| 운영 | 1234567 |
1234567.suitetalk.api.netsuite.com |
| 샌드박스 | 1234567_SB1 |
1234567-sb1.suitetalk.api.netsuite.com |
PlaidCloud는 계정 ID에서 호스트를 자동으로 파생합니다(소문자로 바꾸고 _를 -로 변환). 계정 ID는 NetSuite에 표시된 그대로 입력하며, 샌드박스에는 _SB1 접미사를 포함합니다.
NetSuite 연결 유형으로 연결을 만드십시오(범용 REST 유형이 아닙니다. NetSuite 유형만 호스트를 파생하고 SuiteQL 페이징 동작을 주입합니다). 양식에는 다음 필드가 나타납니다.
식별 정보
섹션 제목: “식별 정보”| 필드 | 유형 | 설명 |
|---|---|---|
| 이름 | 텍스트 | 이 연결의 표시 이름입니다. |
| 별칭 | 텍스트(여러 줄) | 연결에 대한 선택적 별칭 또는 메모입니다. |
| 활성 여부 | 토글 | 연결의 사용 여부입니다. 삭제하지 않고 일시 중지하려면 비활성화합니다. |
| DB 읽기 전용 | 토글 | 연결을 읽기 전용 작업으로 제한합니다. |
| 액세스 유형 | 선택 | 이 연결의 읽기 전용, 쓰기 전용 또는 읽기/쓰기 액세스 수준입니다. |
NetSuite 자격 증명
섹션 제목: “NetSuite 자격 증명”| 필드 | 유형 | 설명 |
|---|---|---|
| 클라이언트 ID | 텍스트 | 통합 레코드의 클라이언트 ID입니다(4단계). |
| 인증서 ID | 텍스트 | 공개 인증서를 업로드할 때 반환된 인증서 ID(JWT kid)입니다(3단계). 시크릿이 아닙니다. |
| NetSuite 계정 ID | 텍스트 | 계정 ID입니다(6단계). 예: 1234567 또는 1234567_SB1. |
| NetSuite 개인 인증서 | 텍스트(PEM) | 여러 줄의 전체 PEM 블록으로 붙여넣은 개인 키입니다(2단계). 암호화되어 저장되며 일반 텍스트로 반환되지 않습니다. |
SuiteQL로 데이터 가져오기
섹션 제목: “SuiteQL로 데이터 가져오기”NetSuite의 레코드 API는 행마다 {id, links}만 반환하므로, PlaidCloud는 REST Request 단계를 통해 SuiteQL로 테이블 형식 데이터를 가져옵니다. NetSuite 연결에 대해 단계를 다음과 같이 구성합니다.
- 메서드 —
POST - 엔드포인트 —
/services/rest/query/v1/suiteql(리터럴 경로이며 호스트는 연결에서 가져옵니다) - 본문 — JSON 형태의 쿼리:
{"q": "SELECT ... FROM ... ORDER BY internalid"}
페이징이나 헤더를 직접 구성하지 마십시오
섹션 제목: “페이징이나 헤더를 직접 구성하지 마십시오”NetSuite 연결에서는 단계가 SuiteQL 세부 사항을 자동으로 주입합니다.
Prefer: transient및Content-Type: application/json헤더.- 서비스에서 고정한 페이지 크기로, 응답의
items/hasMore필드를 기준으로 하는 오프셋 페이징.
페이징 및 파싱 컨트롤과 이 헤더는 그대로 두십시오. 연결이 설정합니다. 엔드포인트, 본문, 그리고 열(아래 참조)만 설정하십시오.
금액 열과 날짜 열의 형식 지정
섹션 제목: “금액 열과 날짜 열의 형식 지정”SuiteQL은 모든 값을 JSON 문자열("1234.56", "2026-01-15", "T")로 반환합니다. 출력 열을 실제 형식으로 직접 정의하십시오. 금액에는 Currency/Decimal, 날짜에는 Date/Datetime, "T"/"F" 플래그에는 Boolean을 사용하면 PlaidCloud가 테이블에 넣는 과정에서 문자열을 형식이 지정된 열로 변환합니다. 빈 문자열은 null로 매핑됩니다. (자동 스키마 추정은 연결의 서비스 구성을 적용하지 않으므로 이를 대신해 주지 못합니다. 열을 직접 정의하십시오.)
알려진 제한 사항
섹션 제목: “알려진 제한 사항”| 제한 사항 | 의미 |
|---|---|
| 열을 직접 정의해야 함 | 스키마 자동 추정은 NetSuite 서비스 구성을 적용하지 않으므로 금액/날짜/부울 열과 해당 형식을 직접 정의하십시오. |
| 페이징은 서비스에서 고정 | 페이징 모드, 경로, 페이지 크기는 연결이 설정하며 단계에서 조정할 수 없습니다. |
| 전체 테이블 교체만 가능 | 가져올 때마다 전체 결과를 다시 추출하며 증분/델타 경로는 없습니다. 예약된 가져오기는 실행할 때마다 전체 테이블을 다시 읽으므로, WHERE 절은 필요한 조각으로 한정하십시오. |
| 다중 통화 / 자회사 | transaction/transactionline에서 amount는 트랜잭션 자체 통화 기준입니다. 자회사 간 단순 SUM(amount)는 연결 기준으로 틀립니다. 자회사 전체를 합계할 때는 연결 금액 또는 환율 변환된 필드를 선택하십시오. |
| 약 100,000행 SuiteQL 한도 | NetSuite는 SuiteAnalytics Connect 없이는 단일 쿼리를 약 100,000행으로 제한합니다. 이를 넘는 직접 작성한 쿼리는 조용히 잘리는 대신, 더 좁은 날짜 범위나 다른 필터를 요청하는 메시지와 함께 즉시 실패합니다. 미리 준비된 NetSuite: 잔액 가져오기 / 총계정원장 상세 단계는 이 한도를 넘지 않도록 날짜 범위를 자동으로 나눕니다. |
| 다중 장부 회계 | 다중 장부 회계(Multi-Book Accounting) 계정에서 TransactionAccountingLine은 트랜잭션 라인마다 장부별로 한 행을 가집니다. 필터링하지 않고 장부 전체를 SUM하면 두 번(또는 N번) 계산됩니다. 미리 준비된 가져오기 단계는 기본 장부를 기본값으로 사용하며, 직접 작성한 쿼리는 장부 간 합계가 실제로 필요한 경우가 아니라면 accountingbook = 1(또는 선택한 장부)로 명시적으로 필터링해야 합니다. |
| 응답 봉투 | 정확한 응답 봉투와 허용되는 범위/역할은 실제 전환 시점에 확인됩니다. 이 커넥터는 NetSuite의 문서화된 형태에 맞춰 만들어졌습니다. |
예제 쿼리
섹션 제목: “예제 쿼리”재무 — 기간별 총계정원장 트랜잭션 라인(형식 지정 및 정렬):
SELECT tl.transaction AS transaction_id, t.trandate AS tran_date, a.acctnumber AS account_number, tl.subsidiary AS subsidiary_id, tl.foreignamount AS amountFROM transactionline tlJOIN transaction t ON t.id = tl.transactionJOIN account a ON a.id = tl.expenseaccountWHERE t.trandate BETWEEN TO_DATE('2026-01-01', 'YYYY-MM-DD') AND TO_DATE('2026-01-31', 'YYYY-MM-DD')ORDER BY tl.transaction, tl.id운영 — 고객별 미결 판매 주문:
SELECT so.tranid AS order_number, so.entity AS customer_id, so.trandate AS order_date, so.status AS order_statusFROM transaction soWHERE so.type = 'SalesOrd' AND so.status = 'SalesOrd:B'ORDER BY so.id