Web API

IIJ IoTサービス はプラットフォーム機能をプログラムから実行するための Web API を公開しています。 IIJ IoTサービス の Web API は IIJ IoTサービス Web API とデータストレージ API があります。

  • IIJ IoTサービス Web API:IoTサービスプラットフォーム機能の実行・設定変更等を実施する Web API
  • データストレージAPI:データストレージに蓄積されたデータにアクセスするための Web API

各 Web API のご利用方法は以下をご参照ください。

IIJ IoTサービス Web API

IIJ IoTサービス Web API は、HTTP リクエストヘッダに認証情報と HTTP リクエストボディにパラメータを指定して実行します。
IIJ IoTサービス Web API は IIJ IoTサービス Web API ドキュメント に認証情報(AccessKeyId / SecretAccessKey)を設定することで Web API をインタラクティブに実行できます。

Web API の実行に必要となる接続情報、認証パラメータやリクエストパラメータの詳細は以下の通りです。

接続情報

Web API は次のエンドポイントにリクエストすることで実行できます。

APIエンドポイントapi.iot.iij.jp
プロトコルHTTPS
ポート443
認証方式

IIJ IoTサービス Web API は HTTP リクエストヘッダーに記述した Authorization ヘッダーを使って正当性の検査を行います。

リクエストヘッダ

以下の HTTP ヘッダーを付与してリクエストする必要があります。

パラメータ名必須

Content-Type

×Content Type を指定します。例:application/json
X-IIJ-ExpireSignature が失効する日時を指定します。フォーマット: YYYY-MM-DDThh:mm:ssZ
※ 協定世界時(UTC)で設定してください。【協定標準時(UTC) = 日本標準時(JST) 9時間
X-IIJ-Signature-MethodSignature を算出する algorithm を指定します。HMAC-SHA256, HMAC-SHA1 をサポートしています。
X-IIJ-Signature-VersionSignature 生成ロジックのバージョンを指定します。2 をサポートしています。
X-Api-VersionAPI のバージョンを指定します。指定する値の詳細は API マニュアルを参照してください。
Signature の算出

Web API を実行するために Authorization ヘッダーに AccessKeyId と Signature を次の形式で設定する必要があります。

Authorization: "IIJIOT " + AccessKeyId + ":" + Signature

Signature はリクエスト情報と SecretAccessKey を使って次の手順で算出します。

1. Web API のリクエストパラメータを確定します。

2. HTTP リクエストメソッド、HTTP リクエストヘッダ文字列、URI エンコードしたパス部分を以下の順序で結合した文字列を生成し、StringToSign とします。

StringToSign = HTTPVerb + "\n\n" +
               ContentType + "\n" +
               "X-IIJ-Expire:" + ExpireDate + "\n" +
               "X-IIJ-Signature-Method:" + SignatureAlgorithm + "\n" +
               "X-IIJ-Signature-Version:" + SignatureVersion + "\n" +
               URLEncodedPath

各パラメータのは次の通りです。

パラメータ名
HTTPVerbリクエストメソッド GET, POST, PUT, DELETE のいずれかを指定します。
ContentTypeContent-Type の値を指定します。Content-Type を指定しない場合は「""」を指定します。
ExpireDateSignature が失効する日時を指定します。フォーマット: YYYY-MM-DDThh:mm:ssZ
※ 協定世界時(UTC)で設定してください。【協定標準時(UTC) = 日本標準時(JST)- 9時間
SignatureAlgorithmSignatureを算出する algorithm を指定します。HMAC-SHA256, HMAC-SHA1 をサポートしています。
SignatureVersionSignature 生成ロジックのバージョンを指定します。2 をサポートしています。
URLEncodedPathURL エンコードされたリクエスト Path を指定します。例: /controls

3. StringToSign を選択した SignatureAlgorithm で SecretAccessKey を使って HMAC を算出します。

4. 算出した HMAC を Base64 エンコードします。

HMAC-SHA256 を利用したシェル上での算出例は次の通りです。

Signature = echo -en StringToSign | openssl dgst -sha256 -binary -hmac SecretAccessKey | base64
リクエストの送信例

算出した Signature を使い、リクエストを送ります。

cURL によるリクエストの例は次の通りです。

curl -i -X HTTPVerb -H "Content-Type: ContentType" \
                    -H "X-IIJ-Expire: ExpireDate" \
                    -H "X-IIJ-Signature-Method: SignatureAlgorithm" \
                    -H "X-IIJ-Signature-Version: SignatureVersion" \
                    -H "X-Api-Version: 1" \
                    -H "Authorization: IIJIOT AccessKeyId:Signature" \
https://api.iot.iij.jp/controls
リクエストパラメータ

API のリクエストのパラメータは IIJ IoTサービス Web API ドキュメント をご参照ください。

データストレージ API

データストレージ API の詳細は データストレージ API マニュアル をご参照ください。

サンプルコード

Web API のサンプルコードです。

Python
sample.py
# coding: utf-8
'''
This is a sample python script code for IIJ IoT Service Web API.
For more information please refer to the manual.
'''
# require packages
# if you do not install packages, please use 'pip' to install.
from __future__ import print_function
from __future__ import unicode_literals
import requests
import hashlib
import hmac
import base64
import datetime

BASE_URL = "https://api.iot.iij.jp"  # not edit
SIGNATURE_ALGORITHM = "HMAC-SHA256"  # or HMAC-SHA1
SIGNATURE_VERSION = 2                # not edit
API_VERSION = 1                      # not edit
# Signature format
STRING_TO_SIGN_FORMAT = (
    "{http_verb}\n\n{content_type}\nX-IIJ-Expire:{expire_date}\nX-IIJ-Signature-Method:{sig_algorithm}\n"
    "X-IIJ-Signature-Version:{sig_version}\n{url_enc_path}"
)

access_key = ""                # your access key
secret_key = ""                # your secret key
# date is ISO format the signature expires.
expire_date = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ")
http_verb = "GET"              # or POST, PUT, DELETE
content_type = ""              # or application/json
url_encoded_path = "/devices"  # specify api path
query = ""                     # if you needed. e.g. ?id=hoge
payload = {}                   # if you needed. We expect json.

string2sign = \
    STRING_TO_SIGN_FORMAT.format(http_verb=http_verb, content_type=content_type,
    expire_date=expire_date, sig_algorithm=SIGNATURE_ALGORITHM, sig_version=SIGNATURE_VERSION,
    url_enc_path=url_encoded_path)

# create signature
_hash = hmac.new(secret_key.encode("utf-8"), string2sign.encode("utf-8"), hashlib.sha256)
# _hash = hmac.new(secret_key.encode("utf-8"), string2sign.encode("utf-8"), hashlib.sha1)
signature = base64.b64encode(_hash.digest()).decode("utf-8")

# require headers
headers = {
    "Content-Type": content_type, "X-Api-Version": str(API_VERSION), "X-IIJ-Expire": expire_date,
    "X-IIJ-Signature-Method": SIGNATURE_ALGORITHM, "X-IIJ-Signature-Version": str(SIGNATURE_VERSION),
    "Authorization": "IIJIOT {access_key}:{signature}".format(access_key=access_key, signature=signature)
}

url = BASE_URL + url_encoded_path + query
request = requests.request(method=http_verb, url=url, headers=headers, json=payload)

print("Status Code: {}".format(request.status_code))
print("Body:\n{}".format(request.text))
Node.js(Javascript)
sample.js
/**
 * This is a sample javascript(Node.js) code for IIJ IoT Service Web API.
 * For more information please refer to the manual.
 */

// require packages
// if you do not install packages, please use 'npm' to install.
const crypto = require('crypto');
const request = require('request');

// this function converts the date to ISO format.
var formatDate = function (date) {
    var format = 'YYYY-MM-DDThh:mm:ssZ';
    format = format.replace(/YYYY/g, date.getFullYear());
    format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
    format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2));
    format = format.replace(/hh/g, ('0' + date.getHours()).slice(-2));
    format = format.replace(/mm/g, ('0' + date.getMinutes()).slice(-2));
    format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2));
    return format;
};

const BASE_URL = 'https://api.iot.iij.jp';  // not edit
const SIGNATURE_ALGORITHM = 'HMAC-SHA256';  // or HMAC-SHA1
const SIGNATURE_VERSION = 2;                // not edit
const API_VERSION = 1;                      // not edit

let date = new Date();
date.setDate(date.getDate() + 1);
var accessKey = '';               // your access key
var secretKey = '';               // your secret key
var httpVerb = 'GET';             // or POST, PUT, DELETE
var contentType = '';             // or application/json
var expireDate;
expireDate = formatDate(date);    // date is ISO format the signature expires.
var urlEncodedPath = '/devices';  // specify api path
var query = '';                   // if you needed. e.g. ?id=hoge
var payload = {};                 // if you needed. We expect json.

var stringToSign = `${httpVerb}\n\n${contentType}\nX-IIJ-Expire:${expireDate}\n` +
  `X-IIJ-Signature-Method:${SIGNATURE_ALGORITHM}\n` +
  `X-IIJ-Signature-Version:${SIGNATURE_VERSION}\n${urlEncodedPath}`;

// create signature
let hmac = crypto.createHmac('sha256', secretKey);
// let hmac = crypto.createHmac('sha1', secretKey);
hmac.update(stringToSign, 'utf8');
var signature = hmac.digest('base64');

// require headers
var headers = {
    'Content-Type': contentType, 'X-Api-Version': API_VERSION, 'X-IIJ-Expire': expireDate,
    'X-IIJ-Signature-Method': SIGNATURE_ALGORITHM, 'X-IIJ-Signature-Version': SIGNATURE_VERSION,
    'Authorization': `IIJIOT ${accessKey}:${signature}`
};

var options = {
    url: BASE_URL + urlEncodedPath + query,
    method: httpVerb,
    headers: headers,
    body: payload,
    json: true
};

request(options, function (error, response, body) {
    console.log('Status Code: %s', response.statusCode);
    console.log('Body:\n%s', JSON.stringify(body));
});
Java
IIJIOTWebApiSample.java
// require packages
// if you can not import JSONObject, you need to install json library
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.json.JSONObject;

/**
 * This is a sample java code for IIJ IoT Service Web API.
 * For more information please refer to the manual.
 *
 * @param accessKey Your access key.
 * @param secretKey Your secret key.
 */
public class IIJIOTWebApiSample {

    public static void main(String[] args) {
        String accessKey = "";               // your access key
        String secretKey = "";               // your secret key
        String httpVerb = "GET";             // or POST, PUT, DELETE
        String contentType = "";             // or application/json
        String urlEncodedPath = "/devices";  // specify api path
        String query = "";                   // if you needed. e.g. ?id=hoge
        // if you needed. We expect json.
        Map<String, Object> payload = new HashMap<String, Object>();
        IIJIOTWebApiSample apiSample = new IIJIOTWebApiSample(accessKey, secretKey);
        String body = apiSample.request(httpVerb, contentType, urlEncodedPath, query, payload);
        System.out.println("Body:\n" + body);
    }

    private static final String BASE_URL = "https://api.iot.iij.jp";
    private static final String SIGNATURE_ALGORITHM = "HMAC-SHA256";  // or HMAC-SHA1
    private static final Integer SIGNATURE_VERSION = 2;               // not edit
    private static final Integer API_VERSION = 1;                     // not edit
    // Signature format
    private static final String STRING_TO_SIGN_FORMAT = "%s\n\n" +
                                                        "%s\n" +
                                                        "X-IIJ-Expire:%s\n" +
                                                        "X-IIJ-Signature-Method:%s\n" +
                                                        "X-IIJ-Signature-Version:%s\n" +
                                                        "%s";

    private String secretKey;
    private String accessKey;

    public IIJIOTWebApiSample(String accessKey, String secretKey) {
        this.accessKey = accessKey;
        this.secretKey = secretKey;
    }

    /**
     * Method for requesting IIJ IoT Web API.
     *
     * @param httpVerb Name of request method.
     * @param contentType Type of request body.
     * @param urlEncodedPath You specify API path.
     * @param query You specify query.
     * @param payload request body you want to send.
     */
    public String request(String httpVerb, String contentType, String urlEncodedPath, String query, Map<String, Object> payload) {
        String expireDate = createExpireDate();
        String signature = createSignature(httpVerb, contentType, expireDate, urlEncodedPath);
        StringBuilder content = new StringBuilder();
        try {
            URL url = new URL(BASE_URL + urlEncodedPath + query);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod(httpVerb);
            // require headers
            connection.setRequestProperty("Content-Type", contentType);
            connection.setRequestProperty("X-Api-Version", API_VERSION.toString());
            connection.setRequestProperty("X-IIJ-Expire", expireDate);
            connection.setRequestProperty("X-IIJ-Signature-Method", SIGNATURE_ALGORITHM);
            connection.setRequestProperty("X-IIJ-Signature-Version", SIGNATURE_VERSION.toString());
            connection.setRequestProperty("Authorization", "IIJIOT " + accessKey + ":" + signature);
            if (payload.size() > 0 && (httpVerb.equals("POST") || httpVerb.equals("PUT"))) {
                connection.setDoOutput(true);
                PrintStream printStream = new PrintStream(connection.getOutputStream());
                printStream.print(new JSONObject(payload).toString());
                printStream.close();
            }
            connection.connect();
            int statusCode = connection.getResponseCode();
            System.out.println("Status Code: " + statusCode);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String inputLine;
            while ((inputLine = bufferedReader.readLine()) != null) {
                content.append(inputLine);
            }
            bufferedReader.close();
            connection.disconnect();
        } catch (IOException e) {
            System.out.println("Connection Error!\n" + e);
            return null;
        }
        return content.toString();
    }

    /**
     * Method for creating signature.
     *
     * @param httpVerb Name of request method.
     * @param contentType Type of request body.
     * @param urlEncodedPath You specify API path.
     * @param expireDate String of Datetime the signature expires is ISO format.
     */
    private String createSignature(String httpVerb, String contentType, String expireDate, String urlEncodedPath) {
        String stringToSign = String.format(STRING_TO_SIGN_FORMAT, httpVerb, contentType,
                expireDate, SIGNATURE_ALGORITHM, SIGNATURE_VERSION, urlEncodedPath);
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
        // SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            // Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(secretKeySpec);
            return Base64.getEncoder().encodeToString(mac.doFinal(stringToSign.getBytes()));
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            System.out.println("Encode Error!\n" + e);
            return null;
        }
    }

    /**
     * Method for creating expireDate.
     */
    private String createExpireDate() {
        return DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
          .format(ZonedDateTime.now().plusDays(1L));
    }

}