Getting started with the API
Almost every Platform API endpoint is SigV4-signed, not Bearer-token-authenticated. So a simple "log in and use the JWT" mental model is wrong here. Plan on two steps after login for REST, plus one more if you also want MQTT.
The auth chain
| Step | Endpoint | Auth in | Auth out | When you need it |
|---|---|---|---|---|
| 1. Login | POST /v1/user/auth/token (Auth & Accounts) | username + password | accesstoken (JWT) | First time, and again every time the JWT expires (~1 hour). Refresh with /v1/user/auth/token/refresh. |
| 2. Get AWS credentials | POST /v1/user/credentials (User Credentials) | JWT (CognitoAuthorizer) | AccessKeyId + SecretAccessKey + SessionToken | Mandatory for every REST call. The JWT itself only authorises this endpoint and a couple of account-level ones - everything else expects a SigV4-signed request (see below). |
| 3. Assume IoT user role | POST /v1/assumed-roles (Role Assumption) | SigV4 with step-2 creds | New AccessKeyId + SecretAccessKey + SessionToken, IoT-scoped or group-scoped | MQTT-only. Required for opening MQTT WebSocket connections (User MQTT API). Also how an admin narrows credentials to a specific group/subgroup. Not needed for any REST endpoint. |
Rule of thumb:
- Calling REST endpoints? Login →
/v1/user/credentials→ done. The step-2 creds work everywhere. - Connecting MQTT? Add step 3 to get IoT-role-scoped creds and use those for the WebSocket handshake.
- Admin scoping to a single group/subgroup? Step 3 with
group/subgroupin the body, then sign your REST calls with the returned creds instead of the step-2 ones.
What "SigV4-signed" means
SigV4 is AWS's standard request-signing scheme. You don't put any one of AccessKeyId, SecretAccessKey, or SessionToken directly into a header. Instead, all three are used together to compute an HMAC signature over the request, and the signature plus the AccessKeyId travel in the Authorization header:
Authorization: AWS4-HMAC-SHA256
Credential=AKIA.../20260501/<region>/execute-api/aws4_request,
SignedHeaders=content-type;host;x-amz-date;x-amz-security-token,
Signature=<hex>
X-Amz-Date: 20260501T120000Z
X-Amz-Security-Token: <SessionToken>
The SecretAccessKey is never sent over the wire — it's only used locally to derive the signature. The SessionToken rides along in X-Amz-Security-Token. If any of the three is missing or wrong, API Gateway rejects the request with a 403.
You almost never hand-roll this. Use:
- AWS SDK (Go, JS, Python, Java, …) — pass the three credentials to a client, the SDK signs every request.
awscurl(github.com/okigan/awscurl) — drop-incurlreplacement that readsAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKENfrom the environment.- AWS CLI v2 with
--sigv4flag.
tl;dr in curl
BASE_URL=https://your-deployment.example.com
USER=you@example.com
PASS=Strongpass123!
# 1. Login -> JWT
JWT=$(curl -s -X POST "$BASE_URL/v1/user/auth/token" \
-H "Content-Type: application/json" \
-d "{\"user_name\":\"$USER\",\"password\":\"$PASS\"}" \
| jq -r .accesstoken)
# 2. JWT -> AWS credentials
CREDS=$(curl -s -X POST "$BASE_URL/v1/user/credentials" \
-H "Authorization: $JWT")
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .access_key_id)
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .secret_access_key)
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .session_token)
# 3. (Optional) Step up to an IoT-scoped role - needed for MQTT etc.
# awscurl POST "$BASE_URL/v1/assumed-roles" --service execute-api ...
# 4. Call any platform endpoint (SigV4-signed)
awscurl --service execute-api "$BASE_URL/v1/user/groups"
awscurl (github.com/okigan/awscurl) handles SigV4 signing for you. The AWS CLI v2 --sigv4 flag works too.
Authentication models in the spec
The Platform API exposes two security schemes; each endpoint page tells you which one applies via the Authorization badge in the right-hand panel.
CognitoAuthorizer — only for two endpoints
A Cognito User Pool JWT in the Authorization header. No Bearer prefix — the raw token:
Authorization: eyJraWQiOiJ...
Used only by /v1/user/credentials and a single admin endpoint. Everything else uses SigV4.
sigv4 — the rest
AWS SigV4 signing with the AccessKeyId / SecretAccessKey / SessionToken triplet from step 2 (or step 3 for IoT operations).
If you're hand-rolling: Authorization header looks like
Authorization: AWS4-HMAC-SHA256 Credential=AKIA.../20260501/<region>/execute-api/aws4_request, SignedHeaders=..., Signature=...
…and the request also needs X-Amz-Date and X-Amz-Security-Token. Easier path: use the AWS SDK or awscurl.
Login flow (Auth & Accounts API)
The full lifecycle for end users lives under /v1/user/auth/*:
| Step | Endpoint | Purpose |
|---|---|---|
| Register a new user | POST /v1/user/auth/signup | Creates the account, mails a verification code. |
| Confirm registration | POST /v1/user/auth/signup/verify | Submits the code from the email. |
| Login (Create Token) | POST /v1/user/auth/token | Exchanges username/password for tokens. Start here. |
| Refresh access token | POST /v1/user/auth/token/refresh | Trade refreshtoken for a new accesstoken. |
| Request password reset | POST /v1/user/auth/password-recovery | Mails a reset code. |
| Complete password reset | POST /v1/user/auth/password-recovery/confirmation | Submits the new password. |
| Change password (logged in) | POST /v1/user/auth/password | Requires a valid access token. |
Admin equivalents live under /v1/admin/auth/* — same shape, different user pool.
The login response shape:
{
"status": "success",
"accesstoken": "eyJraWQ...",
"refreshtoken": "eyJjdHk...",
"idtoken": "eyJraWQ..."
}
Using "Try it out" in this site
Each endpoint page has a right-hand panel. From top to bottom:
- Base URL. Defaults to
https://api.example.com/dev. Click the Edit button on the right edge of that box - a text input appears with the placeholderapi.example.com. Replace it with your deployment's API Gateway hostname (e.g.api.dev.rmng.example.com). The change persists across endpoint pages within the session. - Auth. Pick the security scheme.
CognitoAuthorizertakes the raw JWT in a single field;sigv4takes AccessKeyId, SecretAccessKey, and SessionToken in three fields. - Parameters / Body. Pre-populated from the spec, edit as needed.
- Send API Request. Fires a real request from your browser. Sits at the very bottom of the panel - scroll down past the parameters if you don't see it.
CORS heads-up
API Gateway ships with strict CORS by default, so a browser-side Try-it-out from localhost:3000 (or the docs site itself) will fail preflight unless your stack permits the origin. Either:
- Add
localhost:3000to thecorsAllowedOriginssetting in your CDK config and redeploy, or - Use the equivalent
curl/awscurlsnippet from the page's Code Samples panel.
What about the MQTT APIs?
Devices use X.509 client certs (provisioned during factory NVS generation — see Factory provisioning). User clients use SigV4 over WebSockets — those are the credentials from step 3 (/v1/assumed-roles "Assume IoT user role"), not step 2.
The Node MQTT and User MQTT pages render the AsyncAPI specs inline.