業務の隙間を埋める技術メモ。

「それ、作れるか?」より 「それ、作って大丈夫か?」を考えたい。 業務で“ちゃんと使える”かどうかを、 実際に手を動かして確かめたログを残しています。

Netsuite × kintone API連携でドツボにハマった話

 

「ただのAPI連携でしょ?余裕っしょ」と思っていた時代の自分を殴りたい──そんな話です。

 

最初は、
「NetsuiteからAPIでkintoneのデータを取るだけ」
…そう思って軽い気持ちで作り始めました。

 

ところが、開始3秒でつまずく。
疎通時点で CB_IL02「不正なリクエスト」
先に進めない。あれれ?何もしてないのに。

しかもこの時、恥ずかしながらまだ kintoneのAPI仕様書を1文字も読んでいない というサボりっぷり。
だってあのドキュメント読むの、めんどくさいじゃん…(言い訳)

ちなみにココね。

kintone REST API - cybozu developer network


▼ まず疑った3つの原因

  1. APIキーの権限不足

  2. kintone側のIPアドレス制限

  3. Netsuiteのリクエストがおかしい(おまえか…?)

1 と 2 は動かして確認した方が早いので、とりあえず curl を叩く。
はい、問題なし。ちゃんと返事をくれる。

ということは──
犯人は3の Netsuite(こんちくしょう)しかない。

 

でも待てよ、Netsuite と同じ形式のリクエストをローカルから投げてみようか。

ていう動機から・・・


Pythonで再現コードを作ってみた

せっかくなので“世界にひとりくらい需要があるかもしれない人”のために貼っておきます。

(※個人情報部分は伏せています)

import requests
import json

KINTONE_DOMAIN = "ないしょ.cybozu.com"
KINTONE_APP_ID = ないしょ
KINTONE_API_TOKEN = "ないしょ"

def main():
    url = f"https://{KINTONE_DOMAIN}/k/v1/records.json?app={KINTONE_APP_ID}"

    headers = {
        'X-Cybozu-API-Token': KINTONE_API_TOKEN,
        'Content-Type': 'application/json'
    }

    print("=== Sending Request ===")
    print("URL:", url)
    print("HEADERS:", json.dumps(headers, ensure_ascii=False))

    response = requests.get(url, headers=headers)

    print("\n=== Response Status ===")
    print(response.status_code)

    print("\n=== Raw Response ===")
    print(response.text)

    try:
        data = response.json()
        print("\n=== Parsed JSON ===")
        print(json.dumps(data, indent=2, ensure_ascii=False))
    except json.JSONDecodeError:
        print("\n(Not JSON)")

if __name__ == "__main__":
    main()

この Python でも、CB_IL02「不正なリクエスト」 が出る。
「よしよし、再現したな!おまえは悪くない(Python)」。


▼ 調べてみると…原因は“仕様の地雷”

重い腰を上げて、ようやく kintone API仕様書を確認。

すると、サンプルの headers が自分の書いているものと微妙に違っている。

  • 引用符が ' ではなく "

  • Content-Type の指定がない

この2点を修正したら Python では正常動作!
「やった、犯人はそこか!」

しかし Netsuite のコードに同じ修正を入れても、エラーは消えない。
いよいよ 3 の可能性が濃厚に…。


▼ 結論:Netsuite、勝手に内容いじってた

試行錯誤の結果分かったのはコレでした。

Netsuite からのリクエストは、“受信形式(Accept)を明示的に指定しないと勝手に変なパラメータが付く”

つまり──
“指定していない部分を Netsuite が勝手に補完 → エラー”
という流れ。

なんじゃそりゃ。

で、次の1行を加えたら一発で通りました。

const headers = {
    "X-Cybozu-API-Token": KINTONE_API_TOKEN,
    "Accept": "application/json"
};

はい、やっとデータ取れた。
おつかれ自分。


APIが「苦手」になる本当の理由

APIって「初心者には難しい」とよく言われるけど、
実際は こういう“仕様の違い”という名の地雷 でつまずくことがほとんど。

作った人のクセとか思想とか歴史的経緯とかで、
細かな挙動がバラバラなんですよね。

業界標準があるわけでもないので、今後もこういう落とし穴には悩まされるんだろうなぁ…。


▼ まとめ:動いたから良し!

とにもかくにも、動いたからヨシ!
ふう…。神経すり減らす仕事だよね、IT開発って、、、