# API specification of Ads Management of LINE Ads

# Overview

This document describes API specification of Ads Management of LINE Ads.
This document is intended for the developers who use the API of Ads Management.

This feature is only available to corporate customers

This feature is only available to corporate customers. For more information, contact your LINE representative or make an inquiry through the LINE for Business (opens new window). For details, see LINE Ads (opens new window).

# Authentication

When you access Ads Management API, you have to provide the following items in the request header so the request can be authenticated.
Here are illustrative processes of signing a request.

# 1. Activating a Group for accessing to this API

We send an invitation email to your email address which is applied.
It invites you to a Group which is associated with information for accessing to this API.

# 2. Getting an Access key and a Secret key on the Group setting page of Ad Manager UI

AD Manager UI Setting

You can't see the secret key on first access. Re-generate a secret key from the red marked link below.

AD Manager UI SecretKey

# 3. Generating a request for Ads Management API

# a. Calculating signature of a request

This API authenticates your request with the signature based on JWS. It's necessary to calculate a signature from your request with several operations below.

# i. Constructing JOSE Header

Header is specified by JSON. It includes several claims below.

key description
alg The cryptographic algorithm for signature. Only "HS256" can be specified.
kid This id is the access key which you can see on Ad Manager UI.
type The content type of payload. Only "text/plain" can be specified.

e.g.) Sample of Header

    {
        "alg": "HS256",
        "kid": "LINEADSAMPLE",
        "typ": "text/plain"
    }
# ii. Constructing JWS Payload

Payload is specified by text/plain.
Payload includes some parameters below, and those are concatenated with line feed.

parameter description
Digest-SHA-256 The hex string digest of request body. It is encoded with SHA256.

** When Content-type is 'multipart/form-data', the request body should be ""(empty string).
Content-Type The content type of request body.
e.g.) 'application/json', 'multipart/form-data'

** When Content-type is 'multipart/form-data', no 'boundary' value is needed.
Date The date of generating the request. It should be in format of 'yyyyMMdd'. This value should match the value in 'Date' header.

** The value of 'Date' header should be in format RFC1123 and within the range of ±15 minutes from now.
CanonicalURI Normalized URI of request.

e.g.) Sample of a payload in the case that the request body is '{"accountId": 1}' represented by 'application/json' and it calls '/api/v2.0/accounts/get' at 2018/02/01 00:00:00 GMT.

    40bd039bd8e97662200c4550b522c41ad0ddf21a749fd4a30e94d0f9269778ff
    application/json
    20180201
    /api/v2.0/accounts/get
# iii. Calculating signature

First, creating a JWS Signing Input Value from Header and Payload.
Header and Payload are respectively encoded by base64, and those are concatenated with a comma.

InputValue = Base64(Header).Base64(Payload)

And then, calculating JWS signature from the InputValue with secret key.

Signature = Base64(HMAC-SHA-256(secretKey, InputValue))

In the end, concatenating InputValue and Signature with comma.

InputValue.Signature

# b. Calling API with calculated signature
# i. Setting HTTP Request Headers

This API required some HTTP Request headers below.

Header name value
Content-type The content type of the request
Date The timestamp of generating the request
Authorization Calculated signature with Bearer scheme

e.g)

    Content-type: application/json
    Date: Thu, 01 Feb 2018 00:00:00 GMT
    Authorization: Bearer <Calculated Signature>

# Authentication Examples

# 1. Getting an Access key and regenerating a Secret key on the Group page of Ad Manager UI
# 2. Calculating signature of a request
parameter name value
Access key LINEADSAMPLE
Secret key LINEADSECRETKEYSAMPLE
Request body {"accountId":"1234","operands":[{"name":"test" ,"campaignObjective":"VISIT_MY_WEBSITE"}]}
Content type application/json
Date Thu, 01 Feb 2018 00:00:00 GMT
CanonicalURI /api/v2.0/campaigns/add

Header

{"alg":"HS256","kid":"LINEADSAMPLE","typ":"text/plain"}

Payload

    a97f3860c6fc6e9993e3689a4837d69d49c9b6d7f57d3ccecd899b2f39337c82
    application/json
    20180201
    /api/v2.0/campaigns/add

Signature (with line breaks for display purposes only)

    eyJhbGciOiJIUzI1NiIsImtpZCI6IkxJTkVBRFNBTVBMRSIsInR5cCI6InRleHQvcGxhaW4ifQ==
    .
    YTk3ZjM4NjBjNmZjNmU5OTkzZTM2ODlhNDgzN2Q2OWQ0OWM5YjZkN2Y1N2QzY2NlY2Q4OTliMmYzOTMzN2M
    4MgphcHBsaWNhdGlvbi9qc29uCjIwMTgwMjAxCi9hcGkvdjIuMC9jYW1wYWlnbnMvYWRk
    .
    uVIBEwi07FqAsMoaz3XrylDR0YL2fFfr0NNnX-k9Qi0=
# 3. Creating a campaign
    curl -X POST \
    -H "Content-Type: application/json" \
    -H "Date: Thu, 01 Feb 2018 00:00:00 GMT" \
    -H "Authorization: Bearer {SIGNATURE}" \
    -d
    '{"accountId":"1234","operands":[{"name":"test","campaignObjective":"VISIT_MY_WEBSITE"}]}' \
    https://ads.line.me/api/v2.0/campaigns/add

# Sample Code

get_accounts.py

import base64
import datetime
import hashlib
import hmac
import json
import urllib.request


def calc_sha256_digest(content: str) -> str:
    sha256 = hashlib.new('sha256')
    sha256.update(content.encode())
    return sha256.hexdigest()


def encode_with_base64(value: bytes) -> str:
    return base64.urlsafe_b64encode(value).decode()


# Setting parameters for your request
access_key = "<YOUR_ACCESS_KEY>"
secret_key = "<YOUR_SECRET_KEY>"
content_type = 'application/json'
canonical_uri = '/api/v2.0/accounts/get'
endpoint = 'https://ads.line.me' + canonical_uri
request_body = json.dumps({"page": 1, "results": 100})
jws_header = encode_with_base64(
    json.dumps({
        "alg": "HS256",
        "kid": access_key,
        "typ": "text/plain",
    }).encode()
)

hex_digest = calc_sha256_digest(request_body)
payload_date = datetime.datetime.utcnow().strftime('%Y%m%d')
payload = "%s\n%s\n%s\n%s" % (hex_digest, content_type, payload_date, canonical_uri)
jws_payload = encode_with_base64(payload.encode())

signing_input = "%s.%s" % (jws_header, jws_payload)
signature = hmac.new(
    secret_key.encode(),
    signing_input.encode(),
    hashlib.sha256
).digest()

encoded_signature = encode_with_base64(signature)
token = "%s.%s.%s" % (jws_header, jws_payload, encoded_signature)
http_headers = {
    "Content-Type": content_type,
    "Date": datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'),
    "Authorization": "Bearer %s" % token
}

req = urllib.request.Request(endpoint, request_body.encode(), http_headers)
with urllib.request.urlopen(req) as res:
    resp = res.read()
print(resp.decode())

# API Reference

See LINE Ads Management API reference for details.