Skip to main content
The Integration API uses OAuth2 client_credentials for machine-to-machine authentication. Keycloak service accounts (realm nt24-idp) issue short-lived access tokens bound to your IntegrationOrganization. There is no per-user login flow — every API call is authenticated by a bearer token minted from your client credentials.

Why client_credentials

  • No user in the loop. API calls are server-to-server; no browser redirects or login prompts.
  • Short-lived tokens. Access tokens expire quickly (typically 5 minutes). Leaked tokens auto-expire.
  • Rotatable secrets. Your client_secret rotates via Keycloak without changing any integration code.
  • Standard tooling. Works with every OAuth2-compatible HTTP client (Spring, Axios, httpx, etc.).

Token endpoint

POST https://auth.novatrade24.com/realms/nt24-idp/protocol/openid-connect/token
Request body — application/x-www-form-urlencoded:
grant_type=client_credentials
&client_id=api-client-{your-slug}
&client_secret={secret}
Response:
{
  "access_token": "eyJhbGc...",
  "expires_in": 300,
  "token_type": "Bearer",
  "not-before-policy": 0,
  "scope": "profile email"
}
Use access_token in every API request as Authorization: Bearer <token>.

Token caching

Tokens are valid for expires_in seconds (typically 300). Cache the token and refresh a minute before expiry.
class TokenProvider {
  private token: string | null = null;
  private expiresAt = 0;

  async getToken(): Promise<string> {
    const now = Date.now();
    if (this.token && now < this.expiresAt - 60_000) return this.token;

    const r = await fetch(
      'https://auth.novatrade24.com/realms/nt24-idp/protocol/openid-connect/token',
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({
          grant_type: 'client_credentials',
          client_id: process.env.NT24_CLIENT_ID!,
          client_secret: process.env.NT24_CLIENT_SECRET!,
        }),
      }
    );
    const { access_token, expires_in } = await r.json();
    this.token = access_token;
    this.expiresAt = now + expires_in * 1000;
    return this.token!;
  }
}

Secret rotation

Rotate your client_secret via Keycloak admin API or by contacting support for a regeneration. Process:
  1. Request a new secret (both old and new valid during rotation window).
  2. Update your backend to use the new secret.
  3. Old secret is revoked after you confirm the cutover.
Rotate on a schedule (quarterly recommended) and immediately if you suspect exposure. Rotation does not invalidate already-issued access tokens — only new token requests fail with the old secret.

Organization and partner scoping

Your Keycloak client is linked to exactly one IntegrationOrganization. The organization defines:
  • Authorized partners — the TradePartner UUIDs you can act on behalf of. Every endpoint that touches partner-scoped data requires the partner UUID in the URL path (/partners/{sellerId}/...).
  • Capability flags — features gated on organization entitlement (e.g. allowMarketplaceLedKyc, rateLimitTier).
  • DPA acceptance — Data Processing Agreement version and acceptance timestamp. Requests are rejected with 403 if the DPA is missing or outdated.
Discover both via GET /v1/me at startup.

Troubleshooting

  • Token expired — re-issue via the token endpoint.
  • Wrong realm — verify realms/nt24-idp in the token URL.
  • Malformed Authorization header — must be exactly Bearer <token> (single space).
  • Partner path ({sellerId}) not in your authorized partners list. Check GET /v1/me.
  • Missing capability for the endpoint (e.g. Mode A KYC requires allowMarketplaceLedKyc=true).
  • DPA not accepted for your organization.
  • Wrong client_id or client_secret.
  • Client disabled in Keycloak — contact support.
  • Service Account Roles disabled on the client configuration.
  • grant_type must be exactly client_credentials (lowercase).
  • Do not include username or password — those are for a different grant flow.

Next

Quickstart

Call your first endpoint.

Error reference

Full RFC 7807 problem type catalog.