The endpoints under /auth/v2/ follow Duo's Auth API v2: the same parameter names, signing and answer format.
Basics
| Topic | Rule |
|---|---|
| Base URL | https://auth.wiracode.com |
| Authentication | Authorization: Basic base64(ikey:signature) and Date (how). ping and activation_qr need no signature. |
| Parameters | GET: query string. POST: a JSON object (application/json, signature v5) or a form (application/x-www-form-urlencoded, v2). |
| Users | username: the user's WiraPass email. user_id: the WiraPass user id (UUID). |
| Answers | {"stat": "OK", "response": …}. On failure: {"stat": "FAIL", "code": 40002, "message": …}; the HTTP status is the first three digits of code. |
| Language | status_msg is meant for the user: Indonesian, or English with Accept-Language: en. message of a FAIL is always English, like Duo. |
{
"stat": "FAIL",
"code": 40002,
"message": "WiraPass does not offer the SMS factor. Use push, auto or passcode.",
"message_detail": "factor"
}Endpoints
Liveness Check
GET/auth/v2/ping
No signature.
No signature needed. Use it to see that the service answers and to compare clocks.
Answer 200. Server time (Unix seconds).
{
"stat": "OK",
"response": {
"time": 1790497020
}
}Check Keys and Signature
GET/auth/v2/check
Signed (how).
Answers OK when the integration key, the secret key and your signing are right.
Answer 200. Server time (Unix seconds).
{
"stat": "OK",
"response": {
"time": 1790497020
}
}Errors: 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
Logo
GET/auth/v2/logo
Signed (how).
The WiraPass icon as a 128 x 128 PNG, to show on your sign-in page.
Answer 200. PNG image.
Errors: 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
Start Enrolling a User
POST/auth/v2/enroll
Signed (how).
WiraPass users enroll themselves: they install the app, sign in with this email and turn on approvals. This endpoint returns the download page, a QR code of it and an activation code tied to the email, to be checked with enroll_status.
When no WiraPass account exists for the email yet, user_id is a temporary id that only works with enroll_status. Use username with preauth and auth.
| Parameter | In | Required | Description |
|---|---|---|---|
username | body | Yes | The email the user will sign in to WiraPass with. Required in WiraPass. |
valid_secs | body | No | How long the activation code stays valid, in seconds. Default 86400, clamped to 60 to 604800. |
Answer 200. Activation data.
{
"stat": "OK",
"response": {
"activation_barcode": "https://auth.wiracode.com/auth/v2/activation_qr",
"activation_code": "q3Zb8Xk1LwT0vY7uR5nM2pQ9sD4fG6hJ",
"activation_url": "https://auth.wiracode.com/#download",
"expiration": 1790583420,
"user_id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"username": "rina@example.com"
}
}Errors: 40001, 40002, 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
Enrollment Status
POST/auth/v2/enroll_status
Signed (how).
Answers success once that email has an active approval phone, waiting until then, and invalid when the code is unknown, expired, belongs to another integration or the user_id does not match.
| Parameter | In | Required | Description |
|---|---|---|---|
user_id | body | Yes | The user_id from enroll. |
activation_code | body | Yes | The activation_code from enroll. |
Answer 200. One of success, waiting or invalid.
{
"stat": "OK",
"response": "waiting"
}Errors: 40001, 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
Can This User Be Asked for Approval?
POST/auth/v2/preauth
Signed (how).
When result is auth, the user has an active approval phone: continue with auth. When it is enroll, the user does not use WiraPass yet or has not turned on approvals: deny access and point them to enroll_portal_url. When it is deny, the user just pressed "Not me" on a request from your system, so requests are paused for 15 minutes. WiraPass never answers allow here.
The devices list holds the active approval phones. Their capabilities always include auto and push, and mobile_otp only when the user has a WiraPass backup code. When no phone is signed in to WiraPass the result is still auth, but a push is refused and status_msg suggests the backup code.
| Parameter | In | Required | Description |
|---|---|---|---|
username | body | One of two | The user's WiraPass email (case-insensitive). Send username or user_id, not both. |
user_id | body | One of two | The WiraPass user id (UUID). Instead of username. |
ipaddr | body | No | IP address of the person signing in. On auth it is shown on the phone. |
hostname | body | No | Name of the device used to sign in. On auth it is shown as the device. |
trusted_device_token | body | No | Accepted and ignored (WiraPass does not remember devices). |
client_supports_verified_push | body | No | Accepted and ignored. |
Answer 200. One of auth, enroll or deny.
{
"stat": "OK",
"response": {
"result": "auth",
"status_msg": "Akun aktif.",
"devices": [
{
"device": "9c8b7a6f-5e4d-4c3b-8a29-18f7e6d5c4b3",
"type": "phone",
"name": "Samsung SM-A546E",
"number": "",
"display_name": "Samsung SM-A546E",
"capabilities": [
"auto",
"push",
"mobile_otp"
]
}
]
}
}Errors: 40001, 40002, 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
Ask for Approval or Check a Passcode
POST/auth/v2/auth
Signed (how).
With factor push (or auto), a request goes to every approval phone of the user that is signed in to WiraPass. Without async the call waits until the user answers or it times out (60 seconds). With async=1 it answers at once with a txid for auth_status.
With factor passcode, the server checks the 6-digit backup code from the WiraPass app. Each code works once, there are 5 tries per 5 minutes per user, and the code locks after 10 wrong tries in a row (status locked_out).
The sms and phone factors are not offered by WiraPass and are refused with 40002.
| Parameter | In | Required | Description |
|---|---|---|---|
username | body | One of two | The user's WiraPass email (case-insensitive). Send username or user_id, not both. |
user_id | body | One of two | The WiraPass user id (UUID). Instead of username. |
factor | body | Yes | The value auto is the same as push. |
device | body | No | Either auto (the default) or the id of a phone from preauth. The request still shows on every approval phone of the user. |
async | body | No | Set 1 to get a txid at once instead of waiting. |
type | body | No | Title of the request on the phone. Default: "Masuk ke <integration name>". |
display_username | body | No | Shown as the account on the phone. |
pushinfo | body | No | URL-encoded key=value pairs, under 20000 bytes. Used: app (also from, application), account (user, username), ip (ipaddr), location, device (hostname). Other keys are ignored. |
passcode | body | No | Required with factor passcode: the 6-digit backup code. |
ipaddr | body | No | IP address of the person signing in. On auth it is shown on the phone. |
hostname | body | No | Name of the device used to sign in. On auth it is shown as the device. |
Answer 200. Without async: the final result and status. With async: a txid.
{
"stat": "OK",
"response": {
"result": "allow",
"status": "allow",
"status_msg": "Disetujui. Anda bisa masuk."
}
}Errors: 40001, 40002, 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
Status of a Request
GET/auth/v2/auth_status
Signed (how).
Long-poll: while pending, the server waits up to 8 seconds for a change before it answers waiting. Call again while result = waiting. Only txids of your own integration.
| Parameter | In | Required | Description |
|---|---|---|---|
txid | query | Yes | The txid from auth. |
Answer 200. One of waiting, allow or deny, with a status.
{
"stat": "OK",
"response": {
"result": "waiting",
"status": "pushed",
"status_msg": "Permintaan masuk sudah dikirim ke HP Anda. Buka WiraPass untuk menyetujui."
}
}Errors: 40001, 40002, 40101, 40102, 40103, 40104, 40105, 40106, 42901 (meaning).
QR Code of the Download Page
GET/auth/v2/activation_qr
No signature.
No signature. The image activation_barcode of enroll points to.
Answer 200. PNG image.