スマレジ・プラットフォームAPI 共通仕様書

概要

このドキュメントは、スマレジ・プラットフォームAPIの共通部分の仕様についてをまとめたものです。

スマレジ・プラットフォームAPIを利用する事で、仕様の範囲内で外部システムから、スマレジ・POSをはじめ、スマレジ・ウェイター、スマレジ・タイムカード、各プロダクトのデータにアクセスすることができます。

※各プロダクトのAPI機能詳細については、各仕様書をご参照ください。
※各プロダクトの仕様変更に伴い、APIの仕様が変更される場合があります。


基本情報

各APIにて共通している項目は以下のとおりです。

項目 内容
使用プロトコル HTTP/1.1 (https)
HTTPメソッド GET、POST、PUT、PATCH、DELETE のいずれか
文字コード UTF-8

APIエンドポイント

環境によりエンドポイントURLが異なります。このドキュメントではサンドボックス環境を対象に例を記載しています。

サンドボックス環境 本番環境
アクセストークンAPI https://id.smaregi.dev https://id.smaregi.jp
プラットフォームAPI https://api.smaregi.dev https://api.smaregi.jp

アクセストークン

アプリアクセストークン

アプリとしてアプリユーザーのデータにAPIアクセスするにはアプリアクセストークンを取得する必要があります。

POST https://id.smaregi.dev/app/{契約ID}/token

{契約ID} はアプリユーザーの契約IDに置き換えてください。
契約IDは利用者通知により通知します。

リクエストヘッダー

ヘッダー名 値の説明
Authorization Basic {Base64文字列}
Base64文字列には、クライアントIDとクライアントシークレットを
コロン(:)で結合してBase64エンコードしたものを指定。
Content-Type application/x-www-form-urlencoded

クライアントIDとクライアントシークレットは、スマレジ・デベロッパーズでアプリの「環境設定」ページから確認してください。

リクエストボディ

キー 必須 値の説明
grant_type client_credentials
scope 要求するAPIスコープ。複数の場合は半角スペースで結合して指定。

要求できるAPIスコープは、アプリのAPI設定で有効にしたスコープの中から選択できます。
有効ではないスコープを要求しても無視され、存在しないスコープを含む場合はエラーを返します。

レスポンス

成功時にアクセストークンを含む下記のレスポンスを取得できます。

キー 値の説明
scope アクセストークンで有効なスコープリスト
token_type Bearer
expires_in アクセストークンの有効期間(秒)
* アクセストークン発行時の有効期間は変更になる可能性があります。
access_token アクセストークン

レスポンスの例

Content-Type: application/json

{
    "scope": "{SCOPE_NAME} {SCOPE_NAME} {SCOPE_NAME}",
    "token_type": "Bearer",
    "expires_in": 3600,
    "access_token": "{ACCESS_TOKEN}"
}

リクエスト

各プロダクトのAPIリクエストには、取得したアプリアクセストークンをAuthorizationリクエストヘッダーに含めて送信してください。
※各プロダクトのAPIエンドポイントについては、仕様書ページより、各仕様書をご参照ください。

リクエストの例

スマレジ の店舗(ID:1)情報を取得します。

GET https://api.smaregi.dev/{契約ID}/pos/stores/1 HTTP/1.1
Authorization: Bearer {アクセストークン}

{アクセストークン}はAPIアクセストークン、{契約ID}はアプリユーザーの契約IDに置き換えてください。


レスポンス

成功時

APIリクエストが正常に完了した時は、処理内容に応じたHTTPステータスコードでレスポンスを返却します。

成功レスポンスの例

HTTP/1.1 200 OK
Content-Type: application/json

{
  "productId": "1",
  "productName": "スマレジTシャツ",
  "productCode": "100002454",
  "categoryId": "3",
  "price": "3000",
  "description": "スマレジロゴがプリントされたTシャツです。",
  "displaySequence": "5",
  "ProductPrices": [
    {
      "storeId": "1",
      "priceDivision": "1",
      "startDate": "2020-02-01",
      "price": "2800"
    }
  ]
}

レスポンスの詳細は各仕様書を参照してください。


失敗時

エラーが発生した場合は、エラー原因に応じたHTTPステータスコードおよびメッセージを返却します。
レスポンスの内容は下記の通りです。

レスポンスヘッダー

ヘッダー名 値の説明
Content-Type application/problem+json

レスポンスボディ

キー 値の説明
type エラータイプを識別するURI、もしくは about:blank
title エラーの概要

上記以外のキーを含むことがあります。

エラーレスポンスの例

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json

{
  "type": "about:blank",
  "title": "Bad Request"
}

エラーレスポンスの詳細は各仕様書を参照してください。


HTTPステータスコード (共通部分)

共通するHTTPステータスコードは以下のとおりです。
※詳細は各仕様書を参照してください。

HTTPステータスコード 内容
400 パラメータが不正です
401 アクセストークンが無効です
403 アクセス権限がありません
404 リソースが存在しません
429 一定時間内でのリクエストが多すぎます
500 予期しないエラーが発生しました
503 サービス利用不可
サービスが一時的に過負荷やメンテナンスで使用できません

レート制限

スマレジ・プラットフォームAPIへのリクエストに対して、次のレート制限を設けています。

スロットリング

スロットリングは一定時間内に受け付けるリクエストの回数を制限する仕組みです。 スマレジ・プラットフォームAPIならびにスマレジサービスを安定的に稼働するために、高頻度なリクエストを抑制することが目的になります。

プラットフォームアプリが契約IDへ、一定時間内にリクエストできる回数を制限します。 プラットフォームAPIのすべてのAPIへのリクエストが対象になり、これにはアクセストークンの発行リクエストや、リクエストの結果がエラーレスポンスになったものも含みます。

HTTPメソッドを基に参照系と更新系の2つのAPI種別に分類し、それぞれで制限を行います。

API種別 HTTPメソッド サンドボックス環境 本番環境
参照系API GET (更新系API以外) 10回 / 秒 50回 / 秒
更新系API POST, PUT, PATCH, DELETE 4回 / 秒 20回 / 秒

スロットリング制限を大きく超えるリクエスト送信が長時間続き、サーバー負荷に影響がある場合はクライアントIDやIPアドレスなどを条件にしたリクエスト拒否を行う可能性があります。

※ スマレジは必要に応じて制限仕様を予告なく変更することができます。
※ スロットリングは制限の最大までリクエストできることを保証するものではありません。

上記以外の制限

スマレジはサービスの性能低下や機能停止を防ぐため、予告なく上記以外の追加のレート制限を適用する場合があります。
また当社がスマレジの提供に相当の支障があると判断した場合は、アクセス制限や機能自体の停止等の処置を行うことがあります。

レート制限エラー

プラットフォームAPIへのリクエストがレート制限に達すると、プラットフォームAPIはHTTPステータスコード 429 Too Many Requests のエラーレスポンスを返してリクエストを拒否します。 エラーレスポンスには次のヘッダーとボディが含まれ、 Retry-After ヘッダーには次のリクエストを再試行できるまでの待機秒数が含まれます。

エラーレスポンス例:

HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 10

{
  "type": "about:blank",
  "title": "Too Many Requests",
  "status": 429
}

レート制限への対応

レート制限エラーが発生した場合は、Retry-After ヘッダーに含まれる秒数以上を待機してからリクエストを再試行するようにしてください。 API利用の一般的なベストプラクティスとして、リクエスト再試行に指数バックオフ(Exponential Backoff)を考慮することを推奨します。


Webhook

Webhookは、スマレジで発生したイベントを通知する仕組みです。 特定のイベントが発生した際に、アプリに設定されているWebhook送信先エンドポイントに通知します。 アプリはWebhookで通知を受けることで、スマレジのイベントをトリガーにして処理を行うことができます。

Webhookの設定

スマレジ・デベロッパーズでアプリの「Webhook」ページから、Webhookの利用、送信先エンドポイント、送信するイベントを設定できます。

  • 開発環境のみ、送信先エンドポイントに http:// で始まるURLを設定できますが、本番環境との差異を少なくする https:// で始まるURLを推奨します。
  • 本番環境の設定は、スマレジ・デベロッパーズで申請/公開の後に反映されます。

リクエスト

Webhookによる通知は、Webhook送信先エンドポイントに下記のフォーマットのHTTPS POSTリクエストが送信されます。

リクエストヘッダー

ヘッダー名 値/説明
content-type application/json
smaregi-contract-id イベントの発生した契約ID
smaregi-event イベント名

Webhookで設定したカスタムヘッダーもリクエストヘッダーに含み送信します。

※ヘッダー名は大文字・小文字を区別しないようにしてください。

リクエストボディ

下記のフィールドを持つオブジェクトを、JSONエンコードしたものがリクエストボディに設定されます。

フィールド名 タイプ 値/説明
contractId string イベントの発生した契約ID
event string イベント名
action string イベントのアクション名

他にイベントのデータが含まれます。各API仕様書のWebhookを参照してください。

レスポンス

WebhookのHTTPSリクエストには、ステータスコード 200 でレスポンスボディが空のレスポンスを 3秒以内 に応答してください。 応答にそれ以上の時間がかかる場合は、タイムアウトとして接続を終了し、Webhook送信に失敗したと判断します。

  • レスポンスタイム「3秒以内」という基準は変更される可能性があります。
  • Webhookの受信と受信後の処理を分離して、レスポンスを素早く返しつつ受信後の処理を非同期にすることを推奨します。
  • レスポンスサイズが大きいと、タイムアウトにつながったり、サイズ上限を超えたとしてエラーになることがあります。

再送・リトライ

Webhook送信に失敗しても、現在のところ再送・リトライをおこなっておりません。

  • ネットワーク通信の影響などにより、同じWebhookが重複して送信されることがあります。
  • 重複する内容のWebhookも考慮したWebhook受信処理を推奨します。
  • 通信エラー時の再送処理を検討中です。

通知しないケース

Webhookはアプリ利用中の間に発生したイベントを通知します。 アプリ利用者都合などでアプリが利用停止中の間はWebhookは送信されず、利用停止中に発生したイベントをアプリ利用の再開後に送信することもありません。

ベストプラクティス

Webhookを受信する際のベストプラクティスを以下に記載します。

最小限のイベントのみ送信されるよう設定する

アプリ利用者のスマレジ利用規模やイベントによっては、大量のWebhookが送信される可能性があります。 Webhookの設定で、最小限に必要なイベントのみ送信されるよう選択してください。

Webhook受信後の処理を非同期的に処理する

Webhookの受信時にメッセージキューを利用した非同期処理を検討してください。 受信したWebhookをすぐに処理する必要がなくなり、大量のWebhookが発生した際にもシステムの安定性を保つことができます。 メッセージキューに格納後にレスポンスを応答することでレスポンスタイムの短縮にもつながります。

Webhook受信毎にプラットフォームAPI呼び出しをしない

プラットフォームAPIにはレート制限があるため、Webhookを受信する度にプラットフォームAPIを呼び出すと、大量のWebhookが発生した際にレート制限にかかる可能性があります。 プラットフォームAPIを呼び出す際は、Webhookの受信回数に影響を受けない処理を検討してください。

イベントの通知が前後することを想定する

基本的にイベントが発生した時点でWebhookを送信しますが、一定の順序で送信されるわけではありません。 イベントの通知が前後することを想定した処理を検討してください。

同じイベントの通知が重複することを想定する

さまざまな要因により、同じイベントのWebhookが重複して送信されることがあります。 重複して受信したWebhookを処理しないようにする、もしくは複数回処理しても結果が同じになるよう処理する、などを検討してください。

遅延もしくは届かないことを想定する

ネットワーク遅延、大量Webhookの発生による遅延、Webhook送信システムのメンテナンスや障害などにより、Webhookによるイベントの通知が遅延する、もしくは届かないことが起こりえます。 Webhookの受信のみを前提にせず、能動的にプラットフォームAPIを利用してデータ取得するなどの予備手段を検討してください。

スマレジ・プラットフォームから送信されたリクエストであることを確認する

カスタムヘッダーに独自のシークレット文字列を設定し、受信したWebhookのリクエストヘッダーに同じシークレット文字列が含まれることを確認することで、 送信元がスマレジ・プラットフォームであることを確認する方法があります。 シークレット文字列にはエントロピーの高いランダムな文字列を利用してください。

利用者通知

アプリ利用者に関する下記のイベントを利用者契約通知先URLに通知します。

  • 利用を開始したとき
  • 利用を停止したとき
  • プランを変更したとき
  • オプションを契約したとき
  • オプションを変更したとき
  • オプションを解約したとき
  • 利用中アプリの強制停止が行われたとき
  • 利用中アプリの強制停止が解除されたとき

※これらのイベントは、アプリのお試し利用時も同様に通知します。

リクエスト

Header

ヘッダー名 値/説明
content-type application/json
smaregi-contract-id イベントの発生した契約ID
smaregi-event AppSubscription

利用者通知ではWebhookで設定したカスタムヘッダーは送信されません。

※ヘッダー名は大文字・小文字を区別しないようにしてください。

Body

フィールド名 タイプ 値/説明
event string AppSubscription
action string start : アプリ利用開始時
end : アプリ利用停止時
change-plan : プラン変更時
change-options : オプションのみ変更時
force-stop : アプリ強制停止時
cancel-force-stop : アプリ強制停止解除時
date string アクション発生日(yyyy-mm-dd)
contractId string イベントの発生した契約ID(HeaderのSmaregi-Contract-Idと同じ値)
clientId string 認証認可情報のクライアントID
plan object {"trial_days": "お試し日数(integer)", "price": "プラン合計価格(integer)", "unit_price": "プラン単価(integer)", "quantity": "数量(integer)", "name": "プラン名"}
options array [{"price": "オプション合計価格(integer)", "unit_price": "オプション単価(integer)", "quantity": "数量(integer)", "name": "オプション名"}]

actionchange-optionsオプションのみ契約/変更/解約した場合に通知されます。
以下のようなケースではそれぞれ該当のactionが通知されますのでご注意ください。

  • プランとオプションを同時に利用開始:start
  • プランとオプションを同時に変更:change-plan
  • アプリ自体を解約/強制停止:end / force-stop

Content-Type: application/json

{
    "event": "AppSubscription",
    "action": "start",
    "date": "2020-01-01",
    "contractId": "user_contract",
    "clientId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "plan": {
        "trial_days": 15,
        "price": 3000,
        "unit_price": 1000,
        "quantity": 3,
        "name": "スタンダードプラン"
    },
    "options": [
        {
            "price": 3000,
            "unit_price": 1000,
            "quantity": 3,
            "name": "オプション1"
        }
    ]
}

レスポンス

※「Webhook - レスポンス」をご確認ください。

その他要注意事項

  • Webhook受信後、アプリアクセストークンを発行するとプラットフォームAPIを利用できるようになります。

ログイン

OAuth 2.0 Authorization Code Grant と OpenID Connect に基づいて、スマレジアカウントでのログインを利用できます。

ユーザー認可の要求

ユーザーにログインと認可を要求するには、認可エンドポイントURLにクエリーパラメータを含めてユーザーをリダイレクトしてください。

認可エンドポイントURL

https://id.smaregi.dev/authorize

クエリーパラメーター

パラメーター 必須 値の説明
response_type code
client_id アプリのクライアントID
scope ユーザーに認可を要求するスコープ。
複数の場合は半角スペースで結合して指定。
state ※推奨 CSRF対策に設定するランダムな文字列。
動的にランダムな文字列を生成して利用することを推奨。
redirect_uri ユーザー認可後のリダイレクト先URL。
スマレジ・デベロッパーズでアプリに登録したリダイレクトURIと一致する必要あり。
code_challenge PKCE。動的に生成した code_verifier 値のSHA256ハッシュ値をBase64 URLエンコードした値。
publicクライアントは必須、confidentialクライアントは推奨。
code_challenge_method PKCE。S256 を指定。

scope の指定

OpenID Connect で指定するスコープと、プラットフォームAPIアクセスで必要なスコープを指定してください。

スコープ 説明
openid ログインユーザーの識別子の取得、UserInfoエンドポイントへのアクセス。
email ログインユーザーのアカウントのメールアドレスを参照。 openid の指定が必須。
profile ログインユーザーのプロフィール情報(現在は name のみ)を参照。 openid の指定が必須。
offline_access リフレッシュトークンの取得。

ユーザーアクセストークンでのプラットフォームAPIへのアクセスは、各サービスAPIの対応状況が異なりますので各API仕様書をご確認ください。 対応していないスコープが含まれる場合、エラーをリダイレクトURIへリダイレクトします。

PKCE code_verifier, code_challenge の生成

code_verifier の値は、[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" からなる、43文字~128文字のランダムな文字列を生成してください。
ユーザーアクセストークンの取得時に使用します。

code_challenge の値は、code_challenge_method で指定のメソッドで code_verfifier を計算した結果を使用します。
S256 では code_verifier 値のSHA256ハッシュ値をURLセーフなBase64エンコードした値になります。

confidentialクライアントについてはPKCEの利用を推奨としていますが、将来的に必須とする予定です。

認可コードの取得

ユーザーが認可するとリダイレクトURIにリダイレクトされ、下記のクエリーパラメーターを含みます。

クエリーパラメーター

パラメーター 値の説明
code ユーザーアクセストークン取得に使用する認可コード。
有効期限は5分で、1回のみ利用できます。
state CSRF対策に設定したランダムな文字列。
ユーザー認可の要求時に指定した state 値と一致することを検証してください。

認可コードの有効期限は変更される可能性があります。

エラーレスポンス

ユーザーが認可しなかった場合は下記のクエリーパラメーターを含む結果がリダイレクトされます。

パラメーター 値の説明
error エラーコード
error_description エラー内容
state CSRF対策に設定したランダムな文字列。
ユーザー認可の要求時に指定した state 値と一致することを検証してください。

ユーザーアクセストークンの取得

認可コードを使ってユーザーアクセストークンを取得できます。

POST https://id.smaregi.dev/authorize/token

リクエストヘッダー

ヘッダー名 値の説明
Authorization Basic {Base64文字列}
Base64文字列には、クライアントIDとクライアントシークレットを
コロン(:)で結合してBase64エンコードしたものを指定。
Content-Type application/x-www-form-urlencoded

クライアントIDとクライアントシークレットは、スマレジ・デベロッパーズでアプリの「環境設定」ページから確認してください。

クライアントシークレットがない場合は空文字をクライアントシークレットとして扱ってください。

リクエストボディ

キー 必須 値の説明
grant_type authorization_code
code 取得した認可コード
redirect_uri ユーザー認可の要求時に指定したリダイレクトURIと同じ値を指定。
code_verifier PKCE。[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
からなる、43文字〜128文字の動的に生成したランダムな文字列。
認可エンドポイントでPKCEを指定した場合、必須。

レスポンス

成功時にアクセストークンを含む下記のレスポンスを取得できます。

キー 値の説明
token_type Bearer
expires_in アクセストークンの有効期間(秒)
* アクセストークン発行時の有効期間は変更になる可能性があります。
access_token アクセストークン
scope アクセストークンに付与されたAPIスコープ。
id_token ユーザー認可の要求時にスコープに openid を指定したときのみ含まれる。
refresh_token リフレッシュトークン。
スコープに offline_access を指定したときのみ含まれる。
有効期限 30日間。
  • アクセストークン・リフレッシュトークン発行時の有効期間は変更になる可能性があります。
  • 要求したスコープがアクセストークンに付与されないことがあります。必要なスコープを含むか確認してください。

レスポンスの例

Content-Type: application/json

{
    "token_type": "Bearer",
    "expires_in": 3600,
    "access_token": "{ACCESS_TOKEN}",
    "scope": "{SCOPE}"
}

ユーザー情報を取得

UserInfoエンドポイントからログインユーザー情報を取得できます。ユーザーアクセストークンに openid スコープが必要です。

POST https://id.smaregi.dev/userinfo
ヘッダー名 値の説明
Authorization Bearer {ACCESS_TOKEN} 取得したアクセストークンを指定。

レスポンス

キー 必要スコープ 値の説明
sub openid 契約またはユーザーの識別子
contract openid 契約情報
- id 契約ID
- user_id 契約ID内においてのユーザー識別子
- is_owner ユーザーが契約のオーナーであるか
name profile ログインユーザーのアカウントに登録されている表示用フルネーム
email email ログインユーザーのアカウントに登録されているメールアドレス
email_verified email メールアドレスが検証済みか

レスポンスの例

Content-Type: application/json

{
    "sub": "smaregi:abc123",
    "contract": {
        "id": "smaregi",
        "is_owner": true
    }
}

ユーザーアクセストークンの更新

ユーザーアクセストークンの取得時に offline_access スコープを含めていればリフレッシュトークンを取得でき、リフレッシュトークンを使ってユーザーアクセストークンを更新することができます。

POST https://id.smaregi.dev/authorize/token

リクエストヘッダー

ヘッダー名 値の説明
Authorization Basic {Base64文字列}
Base64文字列には、クライアントIDとクライアントシークレットを
コロン(:)で結合してBase64エンコードしたものを指定。
Content-Type application/x-www-form-urlencoded

クライアントシークレットがない場合は空文字をクライアントシークレットとして扱ってください。

リクエストボディ

キー 必須 値の説明
grant_type refresh_token
refresh_token ユーザーアクセストークン取得時に含まれるリフレッシュトークン。

レスポンス

ユーザーアクセストークンの取得時と同じ項目になります。 レスポンスに含まれる新しいアクセストークン・リフレッシュトークンを使用してください。




Copyright (C) 2020 Smaregi, Inc. All rights reserved.