MagicINFO REST API: sign in with TOTP and get a token
Send POST /MagicInfo/restapi/v2.0/auth with a JSON body containing username, password and a fresh six-digit totp code, then pass the returned token in an api_key header on every other call.
The request
curl -X POST "https://your-server:7002/MagicInfo/restapi/v2.0/auth" \
-H "Content-Type: application/json" \
-d '{"username":"api-user","password":"<password>","totp":"123456"}'
- The field names are
usernameandtotp. Older examples useidandotpValue. That shape is rejected, and the error it produces (401005) looks like a token problem. - For an account with two-step verification, a sign-in without
totpreturns 401. On current MagicINFO 9 builds, plan for every account to need it.
The response
A successful sign-in returns, among other fields:
{ "token": "eyJhbGciOiJIUzUxMiJ9…", "refreshToken": "eyJ…", "userId": "api-user" }
Read token and refreshToken from the top level, and fall back to an items object if your server version nests them there.
Using the token
Send the token on every call in a header named api_key:
curl "https://your-server:7002/MagicInfo/restapi/v2.0/ums/users/me" -H "api_key: <token>"
This is not the standard Authorization: Bearer header, and adding a Bearer prefix breaks the token.
| Lifetime | When it runs out | |
|---|---|---|
token | 30 minutes (1800 s) | calls return 401003 |
refreshToken | 7 days (604800 s) | calls return 401004 |
- In our tests the server also accepts the
refreshTokenin theapi_keyheader for its full seven days. Our own long-running scripts use it that way. The alternative is to sign in again with a fresh code whenever a call returns 401. - The API's published request model also lists a refresh grant (
grantType"refresh_token"with arefreshTokenfield). We have not tested it, so treat it as untested until you have. - Signing in again does not revoke earlier tokens, so two scripts can use the same account.
- To sign out, send
DELETE /MagicInfo/restapi/v2.0/authwith theapi_keyheader.
Generating the TOTP code in a script
The code is a standard time-based one-time password (RFC 6238): a Base32 secret, HMAC-SHA1, a 30-second step and 6 digits. Any TOTP library works. This version uses only the Python standard library:
import base64, hashlib, hmac, struct, time
def totp(secret_b32: str) -> str:
s = secret_b32.replace(" ", "").upper()
key = base64.b32decode(s + "=" * (-len(s) % 8))
counter = struct.pack(">Q", int(time.time()) // 30)
digest = hmac.new(key, counter, hashlib.sha1).digest()
offset = digest[-1] & 0x0F
code = struct.unpack(">I", digest[offset:offset + 4])[0] & 0x7FFFFFFF
return f"{code % 1_000_000:06d}"
- Generate the code immediately before the call. If it is rejected (
401013) near the end of a 30-second window, wait for the next window and retry once. Failed codes count towards the account lockout (401007). - The machine running the script needs an accurate clock.
- Where the secret comes from: the account's two-step enrolment. For a new API user, the first sign-in with only a password returns
401011, and the reply carries the enrolment data (errorDetails.otpAuthInfo.secretKey), just as the web interface shows a QR code. Store that secret as carefully as the password, then send one sign-in with atotpcode generated from it to complete the enrolment. Every password-only attempt generates a new secret, so always use the latest one.
The usual cause of 401005 "Token is invalid"
401005 means the server could not read the token at all, not that it was revoked. In our investigations the cause was always on the client side:
- a
Bearerprefix, or quotes around the value - a byte-order mark or line ending added when the token was saved to a file or piped between programs (Windows PowerShell 5.1 does both)
- one character lost when copying
- an old token kept in a variable
- the outdated
id/otpValuerequest shape
Sign in fresh, send the token exactly as received, and the call should succeed. An expired token gives 401003, not 401005.
How to confirm it worked
GET /MagicInfo/restapi/v2.0/ums/users/me with your api_key header returns HTTP 200 and the signed-in user. After 30 minutes, the same call with the short-lived token returns 401003, which proves your renewal logic is needed and working.
Related
- MagicINFO REST API error codes
- Error 500003 when creating a user
- Two-step verification (OTP)
- Two-factor authentication
- MagicINFO login: find your server's sign-in page
Checked against MagicINFO Server 21.1070 behaviour, October 2026. Behaviour can differ between server builds. Give API integrations their own user account with only the permissions they need, and keep its password and TOTP secret out of source code.