書写学習支援システム (iCAS)

I. 概要

iHandify 書写学習支援システム (iCAS: iHandify Calligraphy Assistant System) は、入力された手書きデータを解析し、筆記の質を反映した採点スコアと、改善に向けた具体的なフィードバックを生成する評価システムです。その名の通り、教育現場や自己学習など、様々な文脈における書字スキルの習得と習熟を支援するために設計されています。

本システムは、画数、筆順、およびきれいさといった基準に基づいて手書き文字を評価します。きれいさの判定項目には、文字のバランス(字形)、筆画(Stroke-ストローク)の終筆形態(とめ・はね・はらい)、筆画の送筆形態(折れ・曲がり)、および筆画間の接続状態(交差・T字接続・L字接続)などが含まれます。これにより、小学校の書写教育だけでなく、漢字、ひらがな、カタカナ、およびアルファベットの学習にも幅広く対応可能です。

iCASの動作には、一対のデジタルインクデータが必要です。一方は「評価対象となる手書きデータ」、もう一方は正解や理想の書き方を示す「手本(exemplar)データ」です。この比較モデルを採用することで、特定の言語や定義済みの文字セットに依存することなく、柔軟かつ動的な運用が可能となっています。

注意点として、本システムは記述された文字自体の文字認識は行いません。あくまで提供された手本データとの比較を通じて、書写の品質を評価します。したがって、適切な手本データさえ用意できれば、あらゆる種類の手書き文字や記号に適用可能です。

現在、小学校学習漢字1,026文字、およびひらがな、カタカナの手本データをサポートしています(詳細は対応文字を参照)。アルファベットおよびその他の文字体系については、今後のアップデートで対応予定です。未対応の文字セットや言語に関する個別要件については、弊社までお問い合わせください。

II. APIの利用方法

iCASは、定義済みの手本データに基づいて手書き入力を評価するためのAPIを提供します。

現在、REST APIでは以下の判定項目をサポートしています。

  • 筆順 (Stroke order)
  • 文字のバランス (Character balance)
  • 筆画向き (Stroke direction)
  • 筆画終筆 (Stroke end type)

筆画送筆(折れ・曲がり)、筆画の接続状態、およびその他のきらいさ判定項目については、今後のアップデートで順次サポート予定です。現在提供されていない機能が必要な場合は、弊社までおお問い合わせください。

以下の表は、Native SDK および REST API で現在サポートされている判定機能の概要です。

  • リアルタイム判定 (Real-time evaluation): 筆記中に実行する機能です。力された画数が手本データの画数に達していない段階での判定です。
  • 全画判定 (Full-character evaluation): 筆記完了後に実行する機能です。入力画数が手本データの画数と一致した段階で、文字全体の判定を行います。
機能 Native SDKサポート状況 REST APIサポート状況
リアルタイム判定 全画判定 リアルタイム判定 全画判定
筆順
筆画長さ
筆画向き
文字のバランス
文字の大きさ
文字の位置
筆画終筆
筆画送筆
筆画位置
筆画接続

APIにアクセスするには、有効な Scoped Public APIキー が必要です。Scoped Public APIキーは、サブスクリプションページで確認できる Secret APIキー を使用して生成できます。各 Scoped Public APIキーは、サブスクリプションプランに基づいて特定のAPIへのアクセス権を付与します。 APIキーの生成および使用方法の詳細については、認証のドキュメントをご参照ください。

1. リクエスト

    https://api.ihandify.com/v1/icas/evaluate

以下に、iCAS APIで使用される主要なパラメータの概要をまとめます。

パラメータ 説明 必須 備考
input 評価対象の入力データ 詳細は デジタルインク形式 を参照 input の画数が手本(character または pattern)の画数より少ない場合、APIは リアルタイム 判定結果を返します。それ以外の場合は 全画 判定結果を返します。
character 評価に使用する手本文字 1文字 character が指定され、かつ対応している場合(詳細は 対応文字 を参照)、pattern は無視されます。
pattern 評価の基準として使用する手本データ 詳細は デジタルインク形式 を参照 character が指定されていない、または対応していない場合は必須です。

上記の表で指定された要件を満たさない場合、APIは 400 Bad Request エラーを返します。

具体的には、以下の場合にエラーが返されます:

  • characterpattern のいずれも指定されていない場合。
  • character が指定されているが未対応であり、かつ pattern が指定されていない場合。
  • input の画数が手本(character または pattern)より多い場合。
  • input または pattern の画数が最大制限である50本を超えた場合。

リクエスト例

 curl -X POST https://api.ihandify.com/v1/icas/evaluate \
     -H "x-api-key: spk_cde88bc3267e3378677404121856330a4feb345c7712e04587cbaa2d9769583a" \
     -F "input=[[[143,160],[144,160],[145,160],[148,160],[151,160],[155,160],[157,160],[161,160],[165,160],[169,160],[172,160],[176,160],[179,160],[182,160],[184,160],[187,160],[190,160],[191,160],[192,160],[193,159]],[[173,140],[171,140],[171,141],[171,143],[171,146],[169,147],[169,150],[168,153],[168,154],[167,157],[167,159],[165,161],[165,164],[165,167],[165,169],[164,173],[164,174],[161,179],[161,182],[161,185],[160,188],[160,192],[157,197],[155,201],[154,206],[152,210],[151,212],[150,216],[148,220],[147,222]],[[183,184],[185,183],[187,183],[190,183],[191,183],[193,183],[194,183],[197,183],[199,183],[201,183],[202,183],[203,183],[204,183],[205,183],[206,183]],[[181,215],[183,215],[184,215],[188,216],[190,216],[194,216],[198,216],[199,216],[201,216],[202,216],[204,216],[205,216],[207,216],[208,216],[210,216],[211,216],[213,216],[214,216],[215,215]]]" \
     -F "character=た"

特化型エンドポイント (Specialized Endpoints)

評価リクエストを処理するために、複数の特化型APIエンドポイントを提供しています。メインとなるエンドポイント(Primary Endpoint)は高度なカスタマイズが可能ですが、特化型エンドポイントは特定の用途向けにプリセットされた構成を提供します。これにより、詳細なドキュメントをすべて読み込むことなく、アプリケーションへの迅速な組み込みが可能です。 特化型APIエンドポイントを利用する場合、すべてのパラメータを明示的に指定する必要はありません。リクエストに含まれないパラメータについては、システム側で定義されたデフォルト値が自動的に適用されます。まずは最小限の設定で実装を開始し、必要に応じて詳細なオプションを段階的に拡張していく運用が可能です。

エンドポイント 説明 input character pattern 仕様
/v1/icas/evaluate/stroke-order 筆順の評価 * ** ** 手本と筆順を比較します。
/v1/icas/evaluate/character-balance 文字バランスの評価 * ** ** input の画数が手本の画数と一致し、書き終えた後にのみ実行されます。
/v1/icas/evaluate/stroke-direction 筆画向きの評価 * ** ** 手本と筆画向きを比較します。
/v1/icas/evaluate/stroke-end-type 筆画終筆の評価 * 手本と筆画終筆を比較します。characterpattern の両方が指定されていない場合、入力データから筆画終筆(詳細は 筆画終筆の種類 を参照)を返します。

* アスタリスク(*)が付いているパラメータは、専用エンドポイント使用時に必須です。
** ダブルアスタリスク(**)が付いているパラメータは、専用エンドポイント使用時に少なくとも1つの指定が必要です。
特化型エンドポイントで定義されているパラメータは、その値が優先されます。リクエスト内で競合する値が指定された場合、それらは無視されます。

専用エンドポイントを使用したリクエスト例

 curl -X POST https://api.ihandify.com/v1/icas/evaluate/stroke-order \
     -H "x-api-key: spk_cde88bc3267e3378677404121856330a4feb345c7712e04587cbaa2d9769583a" \
     -F "input=[[[143,160],[144,160],[145,160],[148,160],[151,160],[155,160],[157,160],[161,160],[165,160],[169,160],[172,160],[176,160],[179,160],[182,160],[184,160],[187,160],[190,160],[191,160],[192,160],[193,159]],[[173,140],[171,140],[171,141],[171,143],[171,146],[169,147],[169,150],[168,153],[168,154],[167,157],[167,159],[165,161],[165,164],[165,167],[165,169],[164,173],[164,174],[161,179],[161,182],[161,185],[160,188],[160,192],[157,197],[155,201],[154,206],[152,210],[151,212],[150,216],[148,220],[147,222]]]" \
     -F "character=た"

このリクエストは、デジタルインクデータを**「筆順評価 (stroke order evaluation)」専用エンドポイント**へ送信する例です。 APIは、入力された最初の2画の筆順を、手本データである文字「た」の筆順と比較し、評価を行います。

 curl -X POST https://api.ihandify.com/v1/icas/evaluate/character-balance \
     -H "x-api-key: spk_cde88bc3267e3378677404121856330a4feb345c7712e04587cbaa2d9769583a" \
     -F "input=[[[143,160],[144,160],[145,160],[148,160],[151,160],[155,160],[157,160],[161,160],[165,160],[169,160],[172,160],[176,160],[179,160],[182,160],[184,160],[187,160],[190,160],[191,160],[192,160],[193,159]],[[173,140],[171,140],[171,141],[171,143],[171,146],[169,147],[169,150],[168,153],[168,154],[167,157],[167,159],[165,161],[165,164],[165,167],[165,169],[164,173],[164,174],[161,179],[161,182],[161,185],[160,188],[160,192],[157,197],[155,201],[154,206],[152,210],[151,212],[150,216],[148,220],[147,222]],[[183,184],[185,183],[187,183],[190,183],[191,183],[193,183],[194,183],[197,183],[199,183],[201,183],[202,183],[203,183],[204,183],[205,183],[206,183]],[[181,215],[183,215],[184,215],[188,216],[190,216],[194,216],[198,216],[199,216],[201,216],[202,216],[204,216],[205,216],[207,216],[208,216],[210,216],[211,216],[213,216],[214,216],[215,215]]]" \
     -F "character=た"

このリクエストは、デジタルインクデータを「字形バランス評価 (character balance evaluation)」専用エンドポイントへ送信する例です。 APIは、筆記が完了した入力データ全体のバランスを、手本データである文字「た」と比較して評価します。

 curl -X POST https://api.ihandify.com/v1/icas/evaluate/stroke-end-type \
     -H "x-api-key: spk_cde88bc3267e3378677404121856330a4feb345c7712e04587cbaa2d9769583a" \
     -F "input=[[[143,160],[144,160],[145,160],[148,160],[151,160],[155,160],[157,160],[161,160],[165,160],[169,160],[172,160],[176,160],[179,160],[182,160],[184,160],[187,160],[190,160],[191,160],[192,160],[193,159]]]" \

このリクエストは、デジタルインクデータを「筆画終筆評価」専用エンドポイントへ送信する例です。 APIは、入力された各画(ストローク)に対し、それぞれの終筆の種類(とめ・はね・はらい)を判別して返します。

2. レスポンス

本サービスは、以下の例に示すように JSON形式 でレスポンスを返します。

なお、サンプル内のコメント(#で表記)は解説用であり、実際のAPIレスポンスには含まれませんのでご注意ください。

全画評価 (Full-character evaluation) のレスポンス例

 HTTP/1.1 200 OK
 Content-Type: application/json; charset=utf-8
 {
 	"data": {
 		"result": {
 			"inputStrokeCount": 6,		    # 入力の画数
 			"exemplarStrokeCount": 6,	    # 手本(標準的な書き方)の画数
 			"strokeOrder": {
 				"result": false,			# 入力の筆順が手本と一致しているかどうか
 				"invalidStrokeIds": [0, 1]	# 筆順が正しくない筆画のインデックス(resultがfalseの場合)。trueの場合は空
 			},
 			"characterBalance": {
 				"score": 0.9				# 文字バランスのスコア(0〜1の値で、手本と比較したバランスの良さを示す。高いほど良い)
 			},
 			"strokeDirection": {
 				"result": false,			# 入力の筆画向きが手本と一致しているかどうか
 				"invalidStrokeIds": [1]     # 方向が正しくない筆画のインデックス(resultがfalseの場合)。trueの場合は空
 			},
 			"strokeEndType": {
 				"result": false,			# 入力の筆画の終筆種別が手本と一致しているかどうか
 				"exemplarTypes": ["sweep", "stop", "stop", "stop", "sweep", "sweep"],   # 手本の筆画の終筆種別(筆順に対応)
 				"inputTypes": ["stop", "sweep", "stop", "stop", "sweep", "hook"],	    # 入力の筆画の終筆種別(筆順に対応)
 				"invalidStrokeIds": [0, 1, 5]  # 終筆種別が正しくない筆画のインデックス(resultがfalseの場合)。trueの場合は空
 			}
 		},
 		"requestId": "0HNKMM36SDFNG:00000001",
 		"date": "2026/10/04 03:25:24"
 	},
 	"code": 200,
 	"message": "Success",
 	"errors": []
 }

このレスポンスには、筆記完了後の全画入力(Full-character)に対する判定結果が含まれます。これには、筆順、文字のバランス、筆画向き、および筆画終筆の判定結果が含まれます。

リアルタイム評価 (Real-time evaluation) のレスポンス例

 HTTP/1.1 200 OK
 Content-Type: application/json; charset=utf-8
 {
 	"data": {
 		"result": {
 			"inputStrokeCount": 2,			# 入力の画数
 			"exemplarStrokeCount": 6,		# 手本(標準的な書き方)の画数
 			"strokeOrder": {
 				"result": false,			# 入力の筆順が手本と一致しているかどうか
 				"invalidStrokeIds": [0, 1]	# 筆順が正しくない筆画のインデックス(resultがfalseの場合)。trueの場合は空
 			},
 			"strokeDirection": {
 				"result": false,			# 入力の筆画向きが手本と一致しているかどうか
 				"invalidStrokeIds": [1]     # 方向が正しくない筆画のインデックス(resultがfalseの場合)。trueの場合は空
 			},
 			"strokeEndType": {
 				"result": false,				        # 入力の筆画の終筆種別が手本と一致しているかどうか
 				"exemplarTypes": ["sweep", "stop"],	    # 手本の筆画の終筆種別(筆順に対応)
 				"inputTypes": ["stop", "sweep"],	    # 入力の筆画の終筆種別(筆順に対応)
 				"invalidStrokeIds": [0, 1]	            # 終筆種別が正しくない筆画のインデックス(resultがfalseの場合)。trueの場合は空
 			}
 		},
 		"requestId": "0HNKMM36SDFNG:00000001",
 		"date": "2026/10/04 03:25:24"
 	},
 	"code": 200,
 	"message": "Success",
 	"errors": []
 }

このレスポンスには、最初の2画が書き終えられた時点でのリアルタイム入力に対する判定結果が含まれます。これには、筆順、筆画向き、および筆画終筆の判定結果が含まれます。

筆画終筆評価 (stroke end type evaluation) のレスポンス例

 HTTP/1.1 200 OK
 Content-Type: application/json; charset=utf-8
 {
 	"data": {
 		"result": {
 			"inputStrokeCount": 2,				    # 入力の画数
 			"strokeEndType": {
 				"inputTypes": ["stop", "sweep"],	# 入力の筆画の終筆種別(筆順に対応)
 			}
 		},
 		"requestId": "0HNKMM36SDFNG:00000001",
 		"date": "2026/10/04 03:25:24"
 	},
 	"code": 200,
 	"message": "Success",
 	"errors": []
 }

このレスポンスには、手本(文字(Character)およびパターン(Pattern))が指定されなかった場合の、入力に対する**筆画終筆(stroke end types)**の判定結果が含まれます。この場合、APIは手本データとの比較を行わず、入力された各画の筆画終筆を解析した結果のみを返します。

レスポンスコード

コード メッセージ 説明
200 Success リクエストは正常に処理されました。
400 Bad Request リクエストの構文またはパラメータが不正です。
403 Forbidden APIキーが無効であるか、有効期限が切れています。
413 Content Too Large 入力データが現在のプランのサイズ制限を超えています。より大きなデータの処理が必要な場合は、お問い合わせの上、プランのアップグレードをご検討ください。
429 Too Many Requests APIキーに設定されたレートリミット(リクエスト回数制限)を超過しました。
500 Internal Server Error サーバー側で予期しないエラーが発生しました。調査が必要な場合は、カスタマーサポートまでご連絡ください。

III. リファレンス

1. 対応文字

本サービスでは、小学校学習漢字 1,026文字、およびひらがな、カタカナの手本データ(exemplar data)をサポートしています。

  • ひらがな(46文字): あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん
  • カタカナ(46文字): アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン
  • 小学1年生の漢字(80文字): 一右雨円王音下火花貝学気九休玉金空月犬見五口校左三山子四糸字耳七車手十出女小上森人水正生青夕石赤千川先早草足村大男竹中虫町天田土二日入年白八百文木本名目立力林六
  • 小学2年生の漢字(160文字): 引羽雲園遠何科夏家歌画回会海絵外角楽活間丸岩顔汽記帰弓牛魚京強教近兄形計元言原戸古午後語工公広交光考行高黄合谷国黒今才細作算止市矢姉思紙寺自時室社弱首秋週春書少場色食心新親図数西声星晴切雪船線前組走多太体台地池知茶昼長鳥朝直通弟店点電刀冬当東答頭同道読内南肉馬売買麦半番父風分聞米歩母方北毎妹万明鳴毛門夜野友用曜来里理話
  • 小学3年生の漢字(200文字): 悪安暗医委意育員院飲運泳駅央横屋温化荷界開階寒感漢館岸起期客究急級宮球去橋業曲局銀区苦具君係軽血決研県庫湖向幸港号根祭皿仕死使始指歯詩次事持式実写者主守取酒受州拾終習集住重宿所暑助昭消商章勝乗植申身神真深進世整昔全相送想息速族他打対待代第題炭短談着注柱丁帳調追定庭笛鉄転都度投豆島湯登等動童農波配倍箱畑発反坂板皮悲美鼻筆氷表秒病品負部服福物平返勉放味命面問役薬由油有遊予羊洋葉陽様落流旅両緑礼列練路和
  • 小学4年生の漢字(202文字): 愛案以衣位茨印英栄媛塩岡億加果貨課芽賀改械害街各覚潟完官管関観願岐希季旗器機議求泣給挙漁共協鏡競極熊訓軍郡群径景芸欠結建健験固功好香候康佐差菜最埼材崎昨札刷察参産散残氏司試児治滋辞鹿失借種周祝順初松笑唱焼照城縄臣信井成省清静席積折節説浅戦選然争倉巣束側続卒孫帯隊達単置仲沖兆低底的典伝徒努灯働特徳栃奈梨熱念敗梅博阪飯飛必票標不夫付府阜富副兵別辺変便包法望牧末満未民無約勇要養浴利陸良料量輪類令冷例連老労録
  • 小学5年生の漢字(193文字): 圧囲移因永営衛易益液演応往桜可仮価河過快解格確額刊幹慣眼紀基寄規喜技義逆久旧救居許境均禁句型経潔件険検限現減故個護効厚耕航鉱構興講告混査再災妻採際在財罪殺雑酸賛士支史志枝師資飼示似識質舎謝授修述術準序招証象賞条状常情織職制性政勢精製税責績接設絶祖素総造像増則測属率損貸態団断築貯張停提程適統堂銅導得毒独任燃能破犯判版比肥非費備評貧布婦武復複仏粉編弁保墓報豊防貿暴脈務夢迷綿輸余容略留領歴
  • 小学6年生の漢字(191文字): 胃異遺域宇映延沿恩我灰拡革閣割株干巻看簡危机揮貴疑吸供胸郷勤筋系敬警劇激穴券絹権憲源厳己呼誤后孝皇紅降鋼刻穀骨困砂座済裁策冊蚕至私姿視詞誌磁射捨尺若樹収宗就衆従縦縮熟純処署諸除承将傷障蒸針仁垂推寸盛聖誠舌宣専泉洗染銭善奏窓創装層操蔵臓存尊退宅担探誕段暖値宙忠著庁頂腸潮賃痛敵展討党糖届難乳認納脳派拝背肺俳班晩否批秘俵腹奮並陛閉片補暮宝訪亡忘棒枚幕密盟模訳郵優預幼欲翌乱卵覧裏律臨朗論

2. 筆画終筆の種類

iCASの筆画の終筆形態検出機能は、日本の伝統的な書道の分類に基づき、以下の5種類のタイプを返します。

  • とめ (Stop): 筆を止めてしっかりと打ち直す、鋭い停止を伴う終筆。
  • はね (Hook): 次の画へ向かうために、跳ね上げるような動作を伴う終筆。
  • はらい (Sweep): 筆を徐々に浮かせながら、払うような動作で抜ける終筆。
  • はね かつ はらい (Hook and Sweep): 「はね」と「はらい」の両方の特性を併せ持つ終筆。
  • はね かつ とめ (Hook and Stop): 「はね」と「とめ」の両方の特性を併せ持つ終筆。

stroke_type