NUACOM API

Getting started

Authentication

The NUACOM API uses token authentication. There is no OAuth. You obtain a token once and send it on every request in a single header:

Authorization: Bearer <token>

Two kinds of token work in that header:

Token Built for Lifetime How you get it
API key (recommended) Scripts, servers, third-party integrations Does not expire; an account admin can disable it Created in the NUACOM portal by an account admin
Session token Access scoped to one specific user 30 days, or 90 days with remember POST /v2/auth/login with that user's email and password

Prefer an API key: it acts as the account admin who created it and never expires. Use a session token only when the calls must be limited to a specific user's permissions, by logging in as that user. See the Auth group for the login flow.

How a call is authenticated

sequenceDiagram
    participant I as Your integration
    participant P as NUACOM portal
    participant API as NUACOM API

    rect rgba(54, 153, 255, 0.08)
        Note over I,API: API key (recommended)
        P-->>I: Account admin creates a key, shown once
        I->>API: GET /v2/extensions<br/>Authorization: Bearer API_KEY
        API-->>I: 200 OK
    end

    rect rgba(26, 156, 107, 0.08)
        Note over I,API: Session token (one user's permissions)
        I->>API: POST /v2/auth/login<br/>{email, pass, remember}
        alt 2FA enabled and the device is new
            API-->>I: 200 {two_fa_enabled: true}, code emailed
            I->>API: POST /v2/auth/login<br/>{email, pass, remember, two_fa_code}
        end
        API-->>I: 200 {session_token, expire_in}
        I->>API: GET /v2/extensions<br/>Authorization: Bearer SESSION_TOKEN
        API-->>I: 200 OK
        I->>API: POST /v2/logout<br/>Authorization: Bearer SESSION_TOKEN
        API-->>I: 200 {updated: 1}
    end

API keys

  1. Sign in to the NUACOM portal as an account admin, open Settings → Apps and Integrations → API Keys and add a key. Give it a name you will recognise later: every call made with it is attributed to that name.
  2. Copy the key when it is shown. A key created since 2026 is a 64-character hexadecimal string shown once, at creation; afterwards the list carries only a masked hint (the first and last four characters), the key's name, who created it and when, and when it was last used. Older keys are 32 characters and keep working.
  3. Send it as Authorization: Bearer <key> on every call.

What to know about a key:

  • It is scoped to the account it was created in and acts as the user who created it: permissions, admin status and call-log visibility all follow that user. If that user is deactivated the key stops working; if they lose admin rights, admin-only endpoints answer 403.
  • It never expires. To revoke it, disable it in the same screen: the change is immediate and permanent, every call made with that key answers 401 from then on, and a disabled key cannot be re-enabled or read back. Create the replacement key first, update the integration, then disable the old one.
  • Renaming a key changes only the name shown in the list; the key itself stays the same.
  • "Last used" is updated every time the key authenticates a call, so an integration that has gone quiet is easy to spot.
  • Treat it like a password: anyone holding it can do everything its creator can do in the portal. Keep it out of logs and repositories; a lost key cannot be shown again, only replaced.

User login

POST https://api.api-nuacom.com/v2/auth/login (reference)

Logs in as one specific user and issues a session token with that user's permissions.

Field Required Notes
email yes
pass yes The password in plain text; the API hashes it. Send it over HTTPS only.
use_raw_pass no true if pass is already the MD5 hash of the password, as lower-case hex
remember no true extends the session from 30 to 90 days
two_fa_code when 2FA applies The six-digit code emailed to the user

A successful login answers 200:

{"session_token": "9f1c0d…", "expire_in": 2592000, "user_id": "123", "user_name": "Jane", "account_id": "IE-00123"}

expire_in is in seconds: 2592000 (30 days), or 7776000 (90 days) with remember. Sessions have a fixed length, they are not extended by use and there is no refresh endpoint: log in again when the token expires.

Two-factor authentication. When the user has 2FA enabled (or the account enforces it) and the device is new, the first call answers 200 with {"code": 200, "two_fa_enabled": true, …} and emails a code. Repeat the same request with two_fa_code set. A code stays valid for two hours.

Failed attempts count toward a per-IP lockout, and the account's IP allow-list and single sign-on restrictions (4004, 4002) apply.

Logout. POST /v2/logout with the session token in the Authorization header expires the session (reference).

If the integration does not need to be limited to one user's permissions, use an API key instead: it needs no password and does not expire.

Errors

From login, 401 with the body {"code": …, "error": "…", "requirements": …}:

code Meaning
401 Wrong email or password, an invalid or expired 2FA code, or too many failed attempts from this IP (five in five minutes)
4001 The password has expired. requirements lists the account's password policy; change it with POST /v2/auth/update-password and log in again
4002 Password login is disabled for this account (single sign-on only)
4004 Logins are not allowed from this IP address

From every other endpoint:

  • 401, body "Unauthorized": the token is missing, invalid or expired, or the user behind it has no active account.
  • 403, body "Forbidden": the endpoint requires an account admin.
  • 422: validation failed; errors lists the fields.
  • 429: more than 3000 requests in a minute; wait the number of seconds in Retry-After.

Other headers

  • Content-Type: application/json for JSON bodies and Accept: application/json.
  • X-Timezone: Europe/Dublin (any IANA name) sets the timezone used to read and format dates on the endpoints that support it; without it the user's profile timezone applies.

Walkthrough with curl

# 1. The normal case: an API key
curl https://api.api-nuacom.com/v2/extensions \
  -H 'Authorization: Bearer YOUR_API_KEY'

# 2. Log in as one specific user: plain-text password
curl -X POST https://api.api-nuacom.com/v2/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"jane@example.com","pass":"password","remember":true}'
# → {"session_token":"9f1c0d…","expire_in":7776000,"user_id":"123","user_name":"Jane","account_id":"IE-00123"}

# 3. An authenticated call with the session token
curl https://api.api-nuacom.com/v2/extensions \
  -H 'Authorization: Bearer SESSION_TOKEN'

# 4. Log out
curl -X POST https://api.api-nuacom.com/v2/logout \
  -H 'Authorization: Bearer SESSION_TOKEN'
# → {"updated":1}