Authentication

The Monogoto API uses JWT Bearer tokens for authentication. This guide covers how to obtain tokens, use them correctly, keep them fresh, and handle the edge cases that trip up most integrations.


How It Works

Authentication follows the standard OAuth 2.0 password grant pattern:

  1. Login — send credentials to /v1/auth/token, receive an access token and a refresh token
  2. Authorise — include the access token in the Authorization: Bearer header on every API request
  3. Refresh — when the access token nears expiry, exchange the refresh token for a new pair at /v1/auth/refresh
  4. Re-login — if the refresh token has expired (after 24 hours of inactivity), repeat step 1
POST /v1/auth/token
    ↓  access_token (4h) + refresh_token (24h)
    
Every API request
    → Authorization: Bearer <access_token>

Before access_token expires
POST /v1/auth/refresh
    → new access_token + new refresh_token (old one invalidated)

Obtaining a Token

Request

POST /v1/auth/token
Content-Type: application/json
{
  "username": "your@email.com",
  "password": "your-password"
}
curl -X POST https://api.monogoto.io/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username": "your@email.com", "password": "your-password"}'

Response

{
  "token_type": "Bearer",
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Field Type Description
token_type string Always "Bearer". Prefix this value to the token in the header.
access_token string Short-lived JWT. Use this on every API call. Valid for 4 hours.
refresh_token string Long-lived JWT. Use this to refresh the access token. Valid for 24 hours, single-use.

Using the Access Token

Include the token in every API request as an Authorization header:

GET /v1/things
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

If the header is missing or the token is invalid, the API returns 401 Unauthorized. If the token lacks the required scope for the endpoint, it returns 403 Forbidden.


Refreshing Tokens

Access tokens expire after 4 hours. Use the refresh flow to extend the session without prompting the user for credentials again.

Request

POST /v1/auth/refresh
Content-Type: application/json
{
  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response

The response shape is identical to the login response — you receive a new access_token and a new refresh_token.

Important: The previous refresh_token is invalidated the moment a new one is issued. Always replace both tokens in storage after a refresh.

Refresh Token Expiry

Refresh tokens are valid for 24 hours from the time of issue. If a refresh attempt returns 401, the refresh token has expired or been invalidated. Fall back to a full login.

async function ensureFreshToken(tokenStore) {
  const BUFFER_MS = 5 * 60 * 1000; // refresh 5 min before expiry

  if (Date.now() < tokenStore.accessTokenExpiresAt - BUFFER_MS) {
    return; // still valid
  }

  try {
    const res = await fetch('https://api.monogoto.io/v1/auth/refresh', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refresh_token: tokenStore.refreshToken }),
    });

    if (res.status === 401) {
      // Refresh token expired — full re-login required
      return login(tokenStore);
    }

    const data = await res.json();
    tokenStore.accessToken = data.access_token;
    tokenStore.refreshToken = data.refresh_token;
    tokenStore.accessTokenExpiresAt = Date.now() + 4 * 60 * 60 * 1000;
  } catch (err) {
    console.error('Token refresh failed:', err);
    throw err;
  }
}

Token Lifecycle at a Glance

Token Valid for Single-use What happens on expiry
access_token 4 hours No API returns 401 — refresh it
refresh_token 24 hours Yes Refresh returns 401 — re-login

API Scopes

Tokens carry scopes that gate access to certain endpoints. The required scope for each endpoint is shown as a badge in the API Reference. Common scopes include:

Scope Access granted
read Read-only access to resources (GET endpoints)
write Create and modify resources (POST, PUT, PATCH)
admin Admin-only endpoints and bulk operations

If your token lacks the required scope, the API returns 403 Forbidden. Contact support@monogoto.io to adjust scope assignments for your account.


Token Storage Recommendations

Environment Recommended storage
Server-side (Node.js, Python, etc.) In-memory, or encrypted at rest in a secrets manager (e.g. AWS Secrets Manager, HashiCorp Vault)
CI/CD pipelines Environment variables injected at runtime — never in the repository
Browser-based apps sessionStorage for short sessions; never localStorage for production secrets
Mobile apps iOS Keychain / Android Keystore

Security Best Practices

Never expose tokens in client-side code or URLs.
Tokens in JavaScript bundles, query strings, or browser history can be extracted trivially. Always pass them via headers from a server-side context.

Use environment variables.
Store credentials in env vars (e.g. MONOGOTO_USER, MONOGOTO_PASS) and inject tokens at runtime. Never hard-code them.

Rotate on breach.
If a token is exposed — in logs, error reports, or a public commit — contact support@monogoto.io immediately to invalidate it. Then rotate your credentials.

Prefer refresh over re-login.
Repeated login calls against /v1/auth/token are rate-limited to 5 per 60 seconds per IP. Use the refresh flow to stay within limits in long-running services.

Log request IDs, not tokens.
When logging API errors for debugging, record the request_id from the error response. This is safe to share with support and provides full traceability.


  • Rate Limits — Auth endpoints have their own IP-based rate limit; understand it before building auto-retry logic
  • Error Reference401 and 403 explained in full with fix guidance
  • Quickstart — End-to-end working example with automatic token refresh