NetSuite の SuiteScript(RESTlet)からkintone APIを叩こうとしたら、401エラーが出て全然つながらない。そんな経験はありませんか? 私はこれで数時間溶かしました。原因と解決策をそのまま書き残しておきます。
- やろうとしていたこと
- 最初に疑ったこと(全部ハズレだった)
- 原因:OAuthトークンのヘッダー設定が間違っていた
- SuiteScriptでの実装例(動作確認済み)
- kintone 401エラーのチェックリスト
- まとめ
- 関連記事
やろうとしていたこと
NetSuiteのScheduled ScriptからkintoneのREST APIを呼び出して、データを同期する仕組みを作ろうとしていました。
構成はシンプルで、こういうイメージです。
NetSuite(Scheduled Script)
↓ HTTP リクエスト
kintone REST API
↓ レスポンス
NetSuite(データ処理)
kintone側のAPIドキュメントを見ながらコードを書いて、いざ実行してみると——
{"code":"CB_AU01","message":"X-Cybozu-API-Token は不正です。"}
HTTPステータスは 401。認証エラーです。
最初に疑ったこと(全部ハズレだった)
エラーメッセージを見て、最初はこんなことを疑いました。
- APIトークンの文字列をコピーミスしているのでは?
- kintone側でIPアドレス制限がかかっているのでは?
- NetSuiteからの外部HTTP通信がブロックされているのでは?
一つひとつ確認しましたが、どれも問題なし。それでも401が出続けます。
原因:OAuthトークンのヘッダー設定が間違っていた
数時間格闘した末に判明した原因は、リクエストヘッダーへのトークンのセット方法が間違っていたことでした。
kintone REST APIの認証には、ヘッダーに以下のように指定する必要があります。
X-Cybozu-API-Token: {APIトークン}
私のコードはこうなっていました。
// ❌ 間違い:Authorizationヘッダーに入れていた
var headers = {
'Authorization': 'Bearer ' + API_TOKEN,
'Content-Type': 'application/json'
};
kintoneはBearerトークン方式ではなく、専用ヘッダー X-Cybozu-API-Token にトークンをそのまま渡す方式です。他のAPIに慣れていると、つい Authorization: Bearer で書いてしまいます。これが原因でした。
正しいコードはこうです。
// ✅ 正しい:X-Cybozu-API-Tokenヘッダーに入れる
var headers = {
'X-Cybozu-API-Token': API_TOKEN,
'Content-Type': 'application/json'
};
SuiteScriptでの実装例(動作確認済み)
NetSuiteのSuiteScript 2.1で実際に動いたコードをそのまま載せておきます。
/**
* @NApiVersion 2.1
* @NScriptType ScheduledScript
*/
define(['N/https', 'N/log'], function(https, log) {
function execute(context) {
var KINTONE_DOMAIN = 'your-domain.cybozu.com'; // ← 自分のkintoneドメインに変更(例:mycompany.cybozu.com)
var APP_ID = '123'; // ← kintone管理画面で確認できるアプリID
var API_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // ← kintoneで発行したAPIトークン
try {
var response = https.get({
url: 'https://' + KINTONE_DOMAIN + '/k/v1/records.json?app=' + APP_ID,
headers: {
'X-Cybozu-API-Token': API_TOKEN, // ← ここが重要
'Content-Type': 'application/json'
}
});
log.debug('ステータス', response.code);
log.debug('レスポンス', response.body);
if (response.code === 200) {
var records = JSON.parse(response.body).records;
log.debug('取得件数', records.length);
// ここでレコードを処理する
}
} catch (e) {
log.error('エラー', e.message);
}
}
return { execute: execute };
});
kintone 401エラーのチェックリスト
同じエラーで詰まっている方向けに、確認すべきポイントをまとめます。
ヘッダーの確認
- [ ]
X-Cybozu-API-Tokenヘッダーを使っているか(Authorization: Bearerではない) - [ ] トークンの文字列に余分なスペースや改行が入っていないか
kintone側の設定確認
- [ ] APIトークンが有効になっているか(kintone管理画面で確認)
- [ ] APIトークンに必要な権限(レコード閲覧・追加など)が付与されているか
- [ ] IPアドレス制限が設定されている場合、NetSuiteのIPが許可されているか
NetSuite側の確認
- [ ]
N/httpsモジュールを使っているか(N/httpではなくHTTPSが必要) - [ ] スクリプトのデプロイ設定でネットワーク通信が許可されているか
まとめ
今回の401エラーの原因は一言でいうと、「kintone専用の認証ヘッダーを知らなかった」 ことでした。
一般的なREST APIは Authorization: Bearer {token} 形式が多いですが、kintoneは独自の X-Cybozu-API-Token ヘッダーを使います。このギャップに気づくまでに数時間かかりました。
同じところで詰まっている方の参考になれば幸いです。
関連記事
#API連携 #401エラー #RESTlet #NetSuite #SuiteScript #kintonet