Type your API server address, e.g. https://api.perusahaan.co.id.
All examples on this page update and can be copied right away.
Start here
Reading SysAd data through the API takes two stages: log in to get a token, then use that token on every data request.
Logging in takes four short steps:
Check accountSend user and pass. You get a list of companies.
Choose entitySend the company id. You get a list of entities.
Choose yearSend the company and entity ids. You get a list of years.
Request tokenSend all the choices above. You get a token.
Already know your company, entity, and year ids? You can go straight to step 4 (request token). Steps 1 to 3 only help you find the ids that apply to your account.
Once you have a token, send it in the token header on every data request. Example: retrieving client data:
Login uses the user and pass headers (plus other ids, depending on the step).
Data requests use the token header. A token is valid for 1 day and is bound to the company, entity, and year you chose.
Use HTTPS when available, because the user, password, and token travel in headers.
Reading and writing
GET endpoints only read data.
POST/PUT endpoints change data and can only be used by API accounts that have been granted write permission. Without it the server answers HTTP 403.
Filtering data (options)
Most data endpoints accept options to narrow the results. The rules are the same everywhere:
options is a JSON array containing one object: [{ ... }]. Only the first object is read.
Each filter is an array of values, e.g. "cust_id": ["C00001", "C00002"]. Data matching any one of the values is included (OR).
When you use several filters at once, data must match all of them (AND).
A filter that is omitted or is an empty array means no restriction. [{}] means all data.
Values must be exactly the same as the codes in SysAd (letter case and spaces).
How to send it (v1).options is sent as a query string and must be URL-encoded, e.g.
?options=%5B%7B%22cust_id%22%3A%5B%22C00001%22%5D%7D%5D.
The curl and JavaScript examples below already do this for you. Exception: the Invoice (AR) endpoint still reads options from a header.
Response format
Every endpoint answers with JSON in the same shape:
true on success, false on failure. Always check this value, not just the HTTP status.
message
Success on success. On failure, a short reason in English.
result
The data. Usually an array of objects (one object per row). It can be an empty array [] when nothing matches.
code
Kept for compatibility. Use success and message.
Status codes and messages
Login or permission failures are signaled with an HTTP 4xx status. Failures on data are signaled with success: false (the HTTP status stays 200).
HTTP status
Message
Meaning and what to do
401
Invalid credential
Wrong username or password.
401
Invalid token
The token is missing, damaged, or not recognized. Request a new token.
401
Token expired
The token is more than 1 day old. Request a new token.
401
User expired
The account has expired. Contact the administrator.
403
User is not registered to use API
The account has not been registered to use the API. Contact the administrator.
403
... don't have access to create or modify data
The account does not have write permission. Contact the administrator.
429
(empty)
Too many login attempts from one IP address (default maximum 10 per minute; the administrator can change this). Wait 1 minute.
200
Invalid token
On data endpoints this can mean the content of options is not valid JSON. Check its shape.
200
Failed when getting data requested.
The data request failed (e.g. the filter does not fit). Check the filter. If it keeps happening, contact the administrator and mention the time it occurred.
200
Invalid options
The content of options is incomplete or has the wrong shape.
Note. Technical details of server errors are intentionally not shown in the response, for security. Administrators can see them in the server log.
Release notes
Security update
For applications that already use this API, a few things need adjusting:
Old tokens are no longer valid. The token format changed. Request a new token through /api/lgn/token.
Error statuses are now HTTP 401 or 403, not 200 after a redirect. The JSON body is unchanged.
Login limit per IP address (default 10 requests per minute; HTTP 429 when exceeded).
Shorter error messages. Technical details exist only in the server log.
Filters are always parameterized. Quotes and special characters in filter values are now safe and treated as plain text.
The /api/v1/finance/ar endpoint shown in the old documentation never worked. The correct address is /api/v1/finance/ar/get.
Approval data changes
Plan approvals are now stored as a JSON array (name, role, time for each approver) and read from the same place in both the Media plan list and Approve a media plan.
The app_by column in plan responses now contains that JSON array (as text). The app_date column is removed; the approval time is inside the array (time).
Approve a media plan (v1) now uses the same app_by format as the original version: text containing a JSON array. Plain text such as "Budi" is rejected.
Endpoint reference
Login
The four first steps to get a token. Shared by all versions.
GET/api/lgn/meCheck account and list companies
Verifies your username and password, then returns the companies you are allowed to access. This is the first step every time you log in. Requires user and pass headers
Note. The result can be empty if the account has not been given access to any company.
The year as text. Sent as the year header when requesting a token.
Value
string
Same as Year.
Text
string
Year to display.
GET/api/lgn/tokenRequest an access token
Exchanges your credentials and your company/entity/year choice for a token. Send this token in the token header on every data endpoint. Requires user and pass headers
Note. A token is valid for 1 day. After that, request a new one with the same steps.
Note. A token is bound to the company, entity, and year you chose. Changing any of them means requesting a new token.
Heads up. Treat the token like a password: do not put it in URLs, public code, or logs.
Heads up. Login endpoints are limited per IP address (default 10 requests per minute; the administrator can change this). Beyond that the server answers HTTP 429; wait 1 minute.
Total yearly budget value, calculated according to the budget type (Original/Forecast/CPRP).
POST/api/v1/master/budget/createCreate a new budget
Creates one new budget for a product. The budget number is generated automatically and returned in the response. Requires the token header; the account must have write permission
Note. Only the first object in the array is processed. To create several budgets, send one request per budget.
Heads up. Requires an API account that has been granted write permission. Without it the server answers HTTP 403.
Heads up. If po_id is already used, the response has success:false, the message "PO Id ... already exist.", and result contains the existing budget.
Plan number, format PLANNO/TYPE.GROUP, e.g. AAA.260001/T.01 (T = television, group 01).
cust_id
string
Client code.
cust
string
Client name.
product_id
string
Product code.
product
string
Product name.
p_date
string
Plan date. May be empty (null).
desc
string
Plan description.
from
string
Start of the airing period.
to
string
End of the airing period.
ref
string
Client reference/PO number.
budget_id
string
Budget number used.
app_by
string
Approval data as a JSON array (text) with the name, role, and time of each approver. Empty if not yet approved.
order_id
string
Media order number.
order_date
string
Order date.
ins
number
Number of insertions/airings.
value
number
Gross value.
paid
number
Amount paid.
nett
number
Nett value.
media
string
Media type.
adtype_id
string
Ad type.
mcs_id
string
MCS number.
mcs_date
string
MCS date.
ar_id
string
Invoice (receivable) number.
ar_date
string
Invoice date. May be empty (null).
status
string
Plan status.
fee
number
Agency fee.
PUT/api/v1/media/plan/approveApprove a media plan
Records the approval of one or more plans. Approval data is stored as a JSON array containing the name, role, and time of each approver. Requires the token header; the account must have write permission
Note. The app_by value you send replaces any previous approval data on that plan. For several approvers, put them all in one array.
Note. The same approval data can be read back through the plan list (app_by column).
Heads up. Requires an API account that has been granted write permission. Without it the server answers HTTP 403.
Heads up. app_by must be text (a string) whose content is JSON, not a raw JSON array. If the format is wrong, the response has success:false with the message "app_by must be in correct json format." or names the missing property (name, role, or time).
The response says "Invalid token" although my token is correct?
If the HTTP status is 200 but the message is Invalid token, the problem is usually the content of options:
it is not valid JSON, not an array, or (for v1) not URL-encoded. Check it with a tool such as jsonlint.com.
If the HTTP status is 401, the token really is not recognized or has expired; request a new token.
The result is empty ([]) although the data exists?
Check that the token was created for the right company, entity, and year; data is read per year according to the token.
Also check the filters: client/product codes must match exactly, and using several filters at once means all of them must match.
How long does a token last? Do I have to log in every time?
A token is valid for 1 day. Store it and reuse it until it expires. You do not need to log in for every request.
I cannot create or approve data (HTTP 403)
Your API account has not been granted write permission. Ask your SysAd administrator to enable it.
The curl examples do not work on Windows
The examples use single quotes (') and \ to continue lines, which suit Git Bash, Linux, and macOS.
In the Windows Command Prompt, write the command on one line and replace single quotes with double quotes (escape double quotes inside the JSON with \).
The easiest way: use an app such as Postman or Insomnia, or use the JavaScript examples.